Ви не увійшли.
что то я переоценил свои силы, в 15 минут не вложился ) пока нашел этот дурацкий шуп ...
в общем прототип ушел на мыло )
servo - классический пример прогромного таймера, сделан с использованием аппаратного таймера для малых частот оличное решение
но по правильному лучше бы исправить analogwrite, но это наверное прийдется в дебри ардуино лезть.
либо после инициализации исправлять,
но мы так делать не будем ) мне привезли десяток робуст от фрискайла, на мои поворотники. харлеевские (если заказчик начнет отвечать в вайбер ), лодку то и на ваш прокт можно что то найти, это industrial mcu, не automotive но тоже хороши, и не только с пивом пойдут )
Остання редакція NoName (2017-05-09 10:14:58)
Неактивний
Процесс не стоит на месте. Прототип уже установлен на подопытный автомобиль.
Уже реализован шим на частоте 25гц. который необходим для управления заводским блоком управления вентиляторами(Штатный на современных мерседесах и фольцвагенах).
Пока открыт вопрос с входами для запуска вентиляторов от блока кондиционера.
Довесил датчик температуры LM75 и ЛСД 16*2 для отладки.
Спасибо NoName, библиотеку и код писал/правил он.
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 00):
* <devgate.info эт gmail.com> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return.
* ----------------------------------------------------------------------------
* Date create: 2017.05.08
* Date change: 2017.05.09
* Date change: 2017.05.22
* Date change: 2017.05.30 add key function control
* ----------------------------------------------------------------------------
*/
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2);
#include <Wire.h>
#include <LM75.h>
LM75 sensor(0x48); // initialize an LM75 object
//#define USE100Hz
char debug_str[100];
#define START_SIGNAL 50
#define KEY1_SIGNAL 50
#define KEY2_SIGNAL 10
#ifdef USE100Hz
#define MAX_SIGNAL 9000
#define MIN_SIGNAL 100
#include <dgm_pwm25.h>
#else
#include <dgm_pwm25.h>
#define MAX_SIGNAL 39000
#define MIN_SIGNAL 1000
#endif
#define USE_FILTER16
#define DEBUG
//#undef DEBUG_PWM
//#define DEBUG_TEST_SYSTEM
#define DEBOUNCE_TIME 100
#define TASK_PROCESS_TIME 1000
int KEY1 = 7;
int KEY2 = 8;
int test_power;
int lcdPower;
typedef enum {
TIMER_EXE = 0,
TIMER_DISABLED = 1,
TIMER_RUN = 2,
} TE_TIMER;
typedef struct
{
int pin_number;
int time_debounce;
unsigned long time_press ;
unsigned long time_release;
unsigned long time_last_press;
unsigned long time_last_release;
int press_level_detect;
bool status_press;
bool status_release;
bool interrupt_press;
bool interrupt_release;
bool need_release;
bool execute;
} tdpkey;
tdpkey key_1;
tdpkey key_2;
// Change these two numbers to the pins connected to your encoder.
// Best Performance: both pins have interrupt capability
// Good Performance: only the first pin has interrupt capability
// Low Performance: neither pin has interrupt capability
// Encoder myEnc(2, 3);
// avoid using pins with LEDs attached
Servo esc;
void setup() {
lcd.begin();
lcd.backlight();
Wire.begin();
esc.attach(9, MIN_SIGNAL, MAX_SIGNAL);
esc.write ( START_SIGNAL );
key_1.time_debounce = 50;
key_1.pin_number = 7;
key_1.press_level_detect = HIGH;
key_2.time_debounce = 50;
key_2.pin_number = 8;
key_2.press_level_detect = HIGH;
pinMode(key_1.pin_number, INPUT);
pinMode(key_2.pin_number, INPUT);
pinMode(KEY1, INPUT);
pinMode(KEY2, INPUT);
Serial.begin(9600);
Serial.println("Start DGM_PWM_25Hz");
}
// long oldPosition = 0xFFFF;
// long newPosition;
long _PWM = 0;
// http://forum.arduino.ua/viewtopic.php?pid=3088#p3088
// GREEN
// CHANGE
bool KEY1CONTROL()
{
static bool key_pressed;
static uint8_t debounce_timer;
if (key_pressed == digitalRead(KEY1)) {
key_pressed = !key_pressed;
debounce_timer = DEBOUNCE_TIME;
}
else if (debounce_timer && !--debounce_timer && key_pressed)
return true;
return false;
}
bool KEY2CONTROL()
{
static bool key_pressed;
static uint8_t debounce_timer;
if (key_pressed != !digitalRead(KEY2)) {
key_pressed = !key_pressed;
debounce_timer = DEBOUNCE_TIME;
}
else if (debounce_timer && !--debounce_timer && key_pressed)
return true;
return false;
}
TE_TIMER system_delay_uint32 ( unsigned long *timer , unsigned long shift )
{
if ( *timer > 0 )
{
if (*timer > shift )
{
*timer -= shift;
return TIMER_RUN;
}
else
{ // save delta time
*timer = ( shift - *timer );
return TIMER_EXE;
}
}
return TIMER_DISABLED;
}
typedef struct
{
int voltage;
int power;
} td_table_unit;
td_table_unit power_table[] =
{
{ 5000, 90 },
{ 2200, 90 },
{ 2100, 85 },
{ 2000, 75 },
{ 1950, 60 },
{ 1900, 40 },
{ 1850, 30 },
{ 1800, 10 },
{ 0, 10 }
};
int voltage_array_pos;
int voltage_array_data[16];
bool enabled_voltage_array = false;
int need_system_power;
int linear_table_interpolation ( int X, int pos )
{
long XXX;
int ret;
long X1, fX1;
long X2, fX2;
if ( pos == 0 ) return ( power_table[0].power ) ;
X1 = power_table[pos-1].voltage;
fX1 = power_table[pos-1].power;
X2 = power_table[pos].voltage;
fX2 = power_table[pos].power;
XXX = fX1 + (fX2 - fX1)*(X - X1)/(X2 - X1);
// Serial.print (" X1: "); Serial.print (X1); Serial.print (" fX1: "); Serial.println (fX1);
// Serial.print (" X2: "); Serial.print (X2); Serial.print (" fX2: "); Serial.println (fX2);
ret = (int) XXX;
if ( ret < 0 ) ret = 0;
if ( ret > 100 ) ret = 100;
return ret;
}
void clear_fkey_interrupt ( tdpkey *pkey )
{
pkey->interrupt_release = false;
pkey->interrupt_press = false;
pkey->need_release = true;
}
//------------------------------------
void fKey (tdpkey *pkey, int time_elapsed )
{
if ( digitalRead( pkey->pin_number) == pkey->press_level_detect )
{
pkey->time_press += time_elapsed;
}
else
{
pkey->time_release += time_elapsed;
}
// кнопка была отжата
if ( pkey->time_release > pkey->time_debounce )
{
if ( pkey->status_release == false )
{
pkey->time_press = 0;
pkey->status_release = true;
pkey->status_press = false;
pkey->interrupt_press = false;
if ( pkey->need_release == false )
{
pkey->interrupt_release = true;
}
pkey->need_release = false;
pkey->time_last_release = pkey->time_release;
pkey->time_release = 0;
#ifdef DEBUG
sprintf ( debug_str,"key_release"); Serial.println ( debug_str );
#endif
}
}
if ( pkey->time_press > pkey->time_debounce )
{
if ( pkey->status_press == false )
{
pkey->status_press = true;
pkey->need_release = false;
pkey->time_release = 0;
pkey->status_release = false;
pkey->interrupt_press = true;
pkey->interrupt_release = false;
pkey->time_last_release = pkey->time_release;
pkey->time_release = 0;
#ifdef DEBUG
sprintf ( debug_str,"key_press"); Serial.println ( debug_str );
Serial.println ( pkey->time_release );
#endif
}
}
return;
}
void loop() {
static unsigned long task_time;
static unsigned long key_time_start_press;
static unsigned long key_time_start_unpress;
TE_TIMER status;
static unsigned long hw_old_system_timer = 0;
unsigned long hw_current_system_timer = 0;
unsigned long delta_task_timer;
int position = 0;
unsigned long test;
int sensorValue = 0;
static int raw_sensorValue = 0;
static int delta = 0;
long voltage;
int power = 95;
int now_status = 0;
long new_duty_cycle = 0;
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
int preset_power = 0;
hw_current_system_timer = millis();
delta_task_timer = hw_current_system_timer - hw_old_system_timer;
hw_old_system_timer = hw_current_system_timer;
status = system_delay_uint32 ( &task_time, delta_task_timer );
fKey (&key_1 , delta_task_timer );
fKey (&key_2 , delta_task_timer );
#ifndef DEBUG_TEST_SYSTEM
raw_sensorValue = analogRead(A0);
#else
// raw_sensorValue &= 0x3FF;
if ( raw_sensorValue > 1024 ) raw_sensorValue = 0;
#endif
#ifdef USE_FILTER16
long sum = 0;
voltage_array_data[voltage_array_pos] = raw_sensorValue;
voltage_array_pos++;
if ( voltage_array_pos >= 16 )
{
enabled_voltage_array = true;
voltage_array_pos = 0;
}
if( enabled_voltage_array )
{
for ( int foo = 0; foo < 16; foo++ )
sum += voltage_array_data[voltage_array_pos];
sum >>= 4; // деление на 16
sensorValue = sum;
}
else
{
sensorValue = raw_sensorValue;
}
#else
sensorValue = raw_sensorValue;
#endif
voltage = sensorValue * (5000.0/1023.0);
// voltage = map(sensorValue, 0, 1023, 0, 5000);
lcdPower = map(need_system_power, 0, 100, 100, 0);
// print out the value you read:
if ( key_1.status_press ) now_status |= 0x0001;
if ( key_2.status_press ) now_status |= 0x0002;
if ( now_status&0x0001 ) preset_power = KEY1_SIGNAL;
else if ( now_status&0x0002 ) preset_power = KEY2_SIGNAL ;
#ifdef DEBUG_PWM
if ( test_power > 100 ) test_power = 0;
esc.write ( test_power );
power = test_power;
#else
if ( voltage < 0 ) voltage = 0;
for ( position = 0 ; ; position++ )
{
if ( voltage >= power_table[position].voltage )
break;
}
need_system_power = linear_table_interpolation (voltage,position);
#endif
if ( preset_power > need_system_power ) esc.write ( preset_power );
else esc.write ( need_system_power );
#ifdef DEBUG
switch ( status )
{
case TIMER_EXE:
case TIMER_DISABLED:
task_time += TASK_PROCESS_TIME;
#ifdef DEBUG_TEST_SYSTEM
raw_sensorValue += 1;
#endif
test_power++;
Serial.print (digitalRead(KEY1));
Serial.print (digitalRead(KEY2));
if ( now_status & 0x0001 )
Serial.print (" D7: ON ");
else Serial.print (" D7: OFF ");
if ( now_status & 0x0002 )
Serial.print ("D8: ON ");
else Serial.print ("D8: OFF ");
Serial.print ("ADC: ");
Serial.print (sensorValue);
Serial.print (" ");
Serial.print ("V: ");
Serial.print (voltage);
Serial.print (" ");
Serial.print ("p: ");
Serial.println (lcdPower);
// get temperature from sensor
// Serial.print("Current temp: ");
// Serial.print(sensor.temp());
// Serial.println(" C");
lcd.clear();
lcd.print("Sens:");
lcd.print(voltage);
lcd.print("V ");
if ( now_status & 0x0001 )
lcd.print("1:ON");
if ( now_status & 0x0002 )
lcd.print("2:ON");
lcd.setCursor(0,1);
lcd.print("FAN:");
lcd.print(lcdPower);
lcd.print("% ");
lcd.print("T:");
lcd.print(sensor.temp());
lcd.print("C");
//delay(150);
/*
Serial.print (" ");
test = esc.readMicroseconds();
Serial.print ("t: ");
Serial.print (test);
Serial.print(" ");
test = esc.read ();
Serial.print ("ms: ");
Serial.println (test);
*/
break;
case TIMER_RUN:
break;
}
#endif
}
Остання редакція yarikne (2017-06-02 22:12:58)
Неактивний