Показать сообщение отдельно
Старый 04.06.2013, 09:11   #457
Bersenev
Бывалый писикарщик
 
Аватар для Bersenev
 
Регистрация: 23.04.2009
Возраст: 53
Город: Ставрополь
Регион: 26
Машина: Opel Zafira 2007
Сообщений: 5,275
Bersenev has a brilliant futureBersenev has a brilliant futureBersenev has a brilliant futureBersenev has a brilliant futureBersenev has a brilliant futureBersenev has a brilliant futureBersenev has a brilliant futureBersenev has a brilliant futureBersenev has a brilliant futureBersenev has a brilliant futureBersenev has a brilliant future
По умолчанию

Цитата:
Сообщение от AlexIz Посмотреть сообщение
Всё как на твоей схеме: 5-аналоговый - кнопки, 5 цифровой - термодатчики.
Пробуй

Код:
//
#include <OneWire.h>
#include <EEPROM.h>
  
#define RES_KEY_FLAG_ 0x77  // Флаг первого запуска скетча

byte bytes[4];

//-----------------------------------------
//- входы(пины) ардуино                   -
//-----------------------------------------
int WIRE_PIN = 5;       // цифровой вход(пин) 1WIRE-шины ( температурные датчики )

int RES_PIN = 5 ;       // аналоговый вход(пин) для резестивных(рулевых) кнопок 

//-----------------------------------------
//- переменные включения функций скетча   -
//-----------------------------------------
boolean is_temperature_sensors = false;
boolean is_res_keys = false;

//-----------------------------------------
//- Переменные для температурных датчиков -
//-----------------------------------------
OneWire  ds(WIRE_PIN);
byte addr[8];            
byte data[12];
unsigned long temperature_sensors_milles;
unsigned long temperature_sensors_wait_milles = 1000; // Интервал передачи данных от температурных датчиков
int t_status = 0;

//-----------------------------------------
//- Переменные для резестивных кнопок     -
//-----------------------------------------
unsigned long  res_dt = 0; 
unsigned long  res_dt_sum=0; 
#define RES_DT_COUNT 500 // Количество считываемых данных
#define RES_DT_SKIP_COUNT 100 // Количество данных, которые надо пропустить при нажатии
#define RES_DT_POINT 6 // Точность
int res_dt_n = 0;
unsigned long res_key=0;
unsigned long res_key_old=0;
unsigned long res_key_wait_first = 500;  // время ожидания после первого нажатия кнопки
unsigned long res_key_wait_next = 250;  // время ожидания до следующего нажатия кнопки
unsigned long res_key_wait_millis = 0;
unsigned long res_key_millis;
unsigned long res_key_array[51][2];
unsigned int res_key_count = 0;
unsigned int res_key_delta = 5; // дельта для определения кода кнопки
  
void setup() 
{ 
  Serial.begin(115200); 
    temperature_sensors_milles = millis();
    t_status = 0;
    res_key_millis = millis();
   
    unsigned int first_run_key = EEPROM.read(0);
    if ( first_run_key == RES_KEY_FLAG_ )
    {
      res_key_count = EEPROM.read(1);
      //EEPROM.write(addr, val);
      for(int i=0; i<res_key_count;i++) 
      { 
        res_key_array[i][0] = (EEPROM.read(i+2) * 256) + EEPROM.read(i+2+50) - res_key_delta; res_key_array[i][1] = res_key_array[i][0] + res_key_delta + res_key_delta; 
      }
    }
    for(int i=res_key_count; i<51;i++) 
    { 
      res_key_array[i][0] = 0xFFFFFFFF; res_key_array[i][1] = 0xFFFFFFFF; 
    }
    
}
 
void loop() 
{
  if (Serial.available() >= 1) // Проверяем наличие команд от компьютера
  {
     switch (Serial.read())
    {

     case 0x02: // включить передачу данных от датчиков температуры
       is_temperature_sensors = true;
     break;

     case 0x06: // включить передачу данных от резестивных кнопок
       is_res_keys = true;
     break;

     case 0x82: // выключить передачу данных от датчиков температуры
       is_temperature_sensors = false;
     break;

     case 0x86: // выключить передачу данных от резестивных кнопок
       is_res_keys = false;
     break;

     case 0xAA: // выключить передачу данных от резестивных кнопок
     {
       while (Serial.available() < 5) {}
       int i = Serial.read();
       bytes[0] = Serial.read();          // преобразовать в 4-байта  
       bytes[1] = Serial.read();  
       bytes[2] = Serial.read(); 
       bytes[3] = Serial.read(); 
       unsigned long key_res_min = 0; key_res_min = bytes[0]; key_res_min = key_res_min * 256 + bytes[1];  
       unsigned long key_res_max = 0; key_res_max = bytes[2]; key_res_max = key_res_max * 256 + bytes[3];  
       res_key_array[i-1][0] = key_res_min; 
       res_key_array[i-1][1] = key_res_max;
     }
     break;

     case 0xAB: // сбросить настройки резестивных кнопок в EEPROM
     {
       EEPROM.write(0,0); // сбросить флаг первого запуска
       res_key_count = 0; // сбросить количество резистивных кнопок 
       EEPROM.write(1,0); //
       for(int i=0; i<51;i++) 
       { 
        res_key_array[i][0] = 0xFFFFFFFF; res_key_array[i][1] = 0xFFFFFFFF; 
       }
     } 
     break;
    }
  } 
  if( is_temperature_sensors ) temperature_sensors();  //  температурные датчики
  if( is_res_keys ) res_keys();                        //  резестивные кнопки
}

//----------------------------------------------------------------------------------
// Функция работы с резестивными кнопками
//----------------------------------------------------------------------------------
void res_keys()
{  
  {
    res_dt = analogRead(RES_PIN); // прочитать данные АЦП 
    if( res_dt >= 0x05 && res_dt <= 0x3F0 )
    { 
      res_dt_n++;
      if( res_dt_n > RES_DT_SKIP_COUNT )
      {
        res_dt_sum += (res_dt << RES_DT_POINT);
        if( res_dt_n == RES_DT_COUNT)
        { 

          res_key = (res_dt_sum / (RES_DT_COUNT - RES_DT_SKIP_COUNT));
          res_key = (((((( res_dt_sum / (( RES_DT_COUNT - RES_DT_SKIP_COUNT ) + (2^(RES_DT_POINT-1)-1) ) >> (RES_DT_POINT-1)) + 1) >> 1) + 1)>> 1)); // + 1) >> 1;
          res_dt_sum = 0; res_dt_n = 0;
        }
       }
    }
    else
    {
      res_dt_sum = 0; res_dt_n = 0; res_key = 0;
      res_key_wait_millis = 0;
    }
  }
  if( res_key_millis + res_key_wait_millis*2 <= millis() ) { res_key_old = 0; }
  if( res_key_millis + res_key_wait_millis <= millis() )
  {
    if( res_key != 0 )
    {
      if( ((res_key_old - res_key_delta) <=  res_key) && (res_key <= (res_key_old + res_key_delta)) )
      {
        res_key_millis = millis(); res_key_wait_millis = res_key_wait_next;
      }
      else
      {
        res_key_millis = millis(); res_key_wait_millis = res_key_wait_first;
      }

        int i = 0; int exit = 0;
        while( res_key_array[i][0] != 0xFFFFFFFF && exit == 0 )
        {
          if( (res_key_array[i][0] <= res_key) && (res_key <= res_key_array[i][1]) ) exit = 1; else i++;
        }
        if( exit == 1 ) 
        { 
          bytes[0] = 0xAA;          // преобразовать в 4-байта  
          bytes[1] = 0;  
          bytes[2] = RES_PIN; 
          bytes[3] = i+1; 
          Serial.write( bytes,4); // отправить прочитаное значение компьютеру
        }
        else
        {
          if( res_key_count < 50 )
          {
            res_key_array[res_key_count][0] = res_key - res_key_delta; res_key_array[res_key_count][1] = res_key + res_key_delta;
            res_key_count++;
            
            EEPROM.write(1, res_key_count); // Запоминаем количество кнопок
            byte one_byte = res_key / 256;
            EEPROM.write(res_key_count+1, one_byte ); // Запоминаем старший байт значения кнопки
            one_byte = res_key - one_byte * 256;
            EEPROM.write(res_key_count+1+50, one_byte ); // Запоминаем младший байт значения кнопки
            EEPROM.write(0, RES_KEY_FLAG_);
          
            bytes[0] = 0xAA;          // преобразовать в 4-байта  
            bytes[1] = 0;  
            bytes[2] = RES_PIN; 
            bytes[3] = res_key_count; 
            Serial.write( bytes,4); // отправить прочитаное значение компьютеру
          }
          else
          {
            bytes[0] = 0xAA;          // преобразовать в 4-байта  
            bytes[1] = 0xAA;  
            bytes[2] = (res_key & 0xFF00) >> 8; 
            bytes[3] = res_key & 0xFF; 
            Serial.write( bytes,4); // отправить прочитаное значение компьютеру
          }
        }
    }
    res_key_old = res_key;
  }
}

//----------------------------------------------------------------------------------
// Функция определение температуры датчиков DS18B20
//----------------------------------------------------------------------------------
void temperature_sensors()
{
  if(t_status == 0)
  {

    if (!ds.search(addr)) 
    {                       // поиск нового датчика
      ds.reset_search();    // если не нашли, сбрасываем поиск в начало
      return;               // и выходим 
    }
  
    // Часть кода, которая ниже, выполняется только если
    // найден новый датчик, с которым ещё не работали в
    // главном цикле до сброса поиска

    if (OneWire::crc8( addr, 7) != addr[7]) // Проверка CRC 
    { 
      return; // Если не пройдена, то в начало главного цикла и продолжаем поиск других датчиков
    }
  
    if (addr[0] != 0x28) // Проверка того, что найденное устройство - температурный датчик DS18B20 
    {        
      return; // Если не он, то опять в начало главного цикла на продолжение поиска
    }
  
    ds.reset();
    ds.select(addr);
    ds.write(0x44,1);
      
    t_status = 1;
  }
  else
  {
    if( temperature_sensors_milles + temperature_sensors_wait_milles < millis() )
    {
      temperature_sensors_milles = millis();

      byte i;

      ds.reset();
      ds.select(addr);
      ds.write(0xBE);
  
      for ( i = 0; i < 9; i++) // получаем данные с датчика
      {         
        data[i] = ds.read();
      }
      bytes[0] = 0xFF; bytes[1] = 0xFF; bytes[2] = 0xFF; bytes[3] = 0xFF; 
      Serial.write( bytes,4); // отправить 0xFFFFFFFF - код температурного датчика
      Serial.write( addr,8); // отправить 8 байтовый номер температурного датчика 
      bytes[0] = 0;          // отправляем байты содержащие температуру  
      bytes[1] = 0;  
      bytes[2] = data[0]; 
      bytes[3] = data[1]; 
      Serial.write( bytes,4); // значение температурного датчика
      t_status = 0;
    } 
  }
}
Bersenev вне форума   Ответить с цитированием