#26 2017-05-08 23:22:00

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Управление вентилятором радиатора автомобиля, разработка.

что то я переоценил свои силы, в 15 минут не вложился )  пока нашел этот дурацкий шуп ...

в общем прототип ушел на мыло )

servo - классический пример прогромного таймера, сделан  с использованием аппаратного таймера для малых частот оличное решение
но по правильному  лучше бы исправить   analogwrite, но это наверное прийдется в дебри ардуино лезть.
либо после инициализации исправлять,

но мы так делать не будем )  мне привезли десяток робуст от фрискайла, на мои поворотники. харлеевские (если заказчик начнет отвечать в вайбер ), лодку то и на ваш прокт можно что то найти, это industrial  mcu, не automotive но тоже хороши, и не только с пивом  пойдут )

Остання редакція NoName (2017-05-09 10:14:58)

Неактивний

#27 2017-05-21 21:48:32

yarikne
Учасник
З Херсон
Зареєстрований: 2017-05-04
Повідомлень: 13

Re: Управление вентилятором радиатора автомобиля, разработка.

Процесс не стоит на месте. Прототип уже установлен на подопытный автомобиль.
Уже реализован шим на частоте 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



}

libraries.rar

Остання редакція yarikne (2017-06-02 22:12:58)

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму