#1 Re: Програмування Arduino » Передача значений температур из Arduino Mega2560 на компьютер » 2014-11-29 14:59:41

Решено.
В одном прерывании обрабатываются все запросы и даются ответы Masterу.
Механизм потери значений переменными при выходе из обработчика не исследован.

Тема закрыта.

#2 Програмування Arduino » Передача значений температур из Arduino Mega2560 на компьютер » 2014-11-19 20:28:11

Technolog
відповідей: 1

Добрый день.

Суть проблемы:
Arduino Mega 2560 с четырьмя подключенными датчиками температуры.
Программа запущенная на компьютере (Master) с интервалом в 1 минуту через USART запрашивает поочередно температуры измеренные 4-мя датчиками.
По приходу первого байта запроса срабатывает обработчик прерывания ISR(USART0_RX_vect).
При некорректном принятии запрос игнорируется, при корректном -
в обработчике формируется массив символов запроса, определяется условный адрес запрашиваемого датчика,
формируеся ответ Masterу, отправляеся, и здесь выход из прерывания. Идет 4 запроса-ответа подряд, естественно еще минимум три раза вызывается прерывание.
Первый ответ содержит действительную температуру датчика, поледующие три ответа (2, 3 и 4 датчики) содержат ноль по температуре.
Причина: обнуляются переменные температур 2, 3 и 4 при первом выходе из прерывания по USART.
Переменные температур обьявлены как volatile.

Где ошибка? Подскажите способ решения?

#include <avr/interrupt.h> //библиотека прерываний
#include <OneWire.h>
#include <DallasTemperature.h> 
 ...
   переменные задействованные в void loop() и в обработчике 
   прерывания ISR(USART0_RX_vect) определены как  volatile float
volatile float val_T1;  температура 1-го датчика
volatile float val_T2;  температура 1-го датчика
volatile float val_T3;  температура 1-го датчика
volatile float val_T4;  температура 1-го датчика
volatile unsigned char Symb;
volatile unsigned char s[16];
 ... 
   функция инициализации прерывания по приходу байта ч/з USART
void USART_Init(int baudrate )
 {
   UBRR0H = baudrate>>8;
   UBRR0L = baudrate;
   UCSR0B = (1<<RXCIE0)|(1<<TXCIE0)|(1<<RXEN0)|(1<<TXEN0);
   UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
   sei();
 }
 ... 
void setup() 
{ 
 USART_Init(103); 
 ...
}
 ...
void USART_Transmit( unsigned char data )//Функция отправки данных
{...}
unsigned char USART_Receive( void )//Функция приема данных
{...}
 ... 
void loop()
{  
 * * * * *  
 ...
sensors_1.requestTemperatures();
val_T1 = sensors_1.getTempC(add_K1T1);
val_T2 = sensors_1.getTempC(add_K1T2);
val_T3 = sensors_1.getTempC(add_K1T3);

sensors_2.requestTemperatures();
val_T4 = sensors_2.getTempC(add_K1T4);
}
 ... 
//Обрабатываем прерывание по поступлению байта
ISR(USART0_RX_vect)
{  	
  // UDR0; //прининятый байт  
  s[14] = 0;
  if (UDR0 == 35) 
{
  for (byte ii=2; ii<=14; ii++) {s[ii] = USART_Receive();}
  if (s[14] == 13) 
{
  ArrReq[0] = s[2];
  ArrReq[1] = s[3];  
 ...
    определяется условный адрес опрашиваемого датчика
    Sens_addres = 128*ArrOut[1] + 64*ArrOut[2] + ... + ArrOut[8];    
 ...
    переменной Temp присваивается значение температуры измеренное датчиком 
if (Sens_addres == 120) {Temp = val_T1;}  1-й датчик
if (Sens_addres == 121) {Temp = val_T2;}  2-й датчик
if (Sens_addres == 122) {Temp = val_T3;}  3-й датчик
if (Sens_addres == 123) {Temp = val_T4;}  4-й датчик
 ...
// отправка строки символов, (ответ на запрос Master'a): 
    delay(2); // требуется по протоколу обмена с Master'ом
    for (byte i=1; i<=27; i++) {USART_Transmit(ArrPac[i]);}
}
}
}

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