waski
March 9, 2014, 9:36am
1
Dear All
I'm looking for a help with code for my project. I've got many usefull advices here and got my code working but there is still some kind of error. But first things first :
What I'm trying to do is to read four 1-wire to RS485 converters. I can provide link to those devices but web page is in Polish so I don't think it's gonna be useful Each unit has two DS18B20 sensors attached. To read this unit, you need to send a command : " T00\r " where 00 is address of unit and \r is carriage return sign. Unit is quite slow so there has to be about 2ms pause beetween each sign sended as a command. When unit gets a valid command , it response by sending a string : ' T00= 20.0"C;T01= 21.0"C ' .
T00 and T01 are adresses of connected DS sensors , then there are teperature readings. The " sign is degree sign . So far I have four of those devices : T00 , T02, T04, T06 . But there will be more of them - maybe 10. After reading string from each unit, I need to get the temperatures readings into float variables . So far there is 8 variables : temp_szk_1 , temp_szk_2 and so on . In case os failure of DS18B20 sensor, unit puts string 'Failure' after address of this sensor. I'm polling each unit every 4 second but it can be slower or faster - timing is not so important.
The code I'have IS working but I get random errors - from time to time I'm getting ZEROS at different temperature reading or , sometimes, incorrect values ( for egzample 35.5 degrees but real temperature is 20.0 degrees ) .
Since this is a temperature monitoring project, wrong values are wery confusing. So I'm asking for a help . I'm ready to pay some small fee.
I've stripped the code from LCD stuff, sending variables to another arduino etc.
Code in next post :
waski
March 9, 2014, 9:36am
2
#include "U8glib.h"
#include <Wire.h>
#include <Time.h>
#include <EasyTransfer.h>
byte adr_czujnika_1 ; // address of first DS18B20 sensor on each unit
byte adr_czujnika_2 ; // address of second DS18B20 sensor on each unit
byte wezel ;
byte a = 0 ; // while loops counters to make sure command was sended only once in loop.
byte b = 0 ;
byte c = 0 ;
byte d = 0 ;
static char input[27]; // char array to store incoming data
static char input_copy[27]; //copy of input char array to store adress
static uint8_t i;
static uint8_t j;
static char *s0, *s1, *s2, *s3, *s4, *s5 , *failure1, *failure2 ;
static unsigned long lastMillis = 0;
static int timer_1 = 0; // a repeating timer max time 32768 mS = 32sec use an unsigned long if you need a longer timer
static int timer_2 = 0; // 300ms timer
static int timer_3 = 0; // timer 500ms
#define TIMER_INTERVAL_1 1000 // 1S interval
#define TIMER_INTERVAL_03 300 // 300ms
#define TIMER_INTERVAL_05 500
#define INTERWAL_LCD 100 // LCD
int lcd_counter = 0; // LCD loop counter
int read_time = 0; // time to read RS485 unit
const byte RS_PIN = 3; // RS485 send / read control pin
EasyTransfer ETin, ETout;
////////////////////////////////////////////////////////////////////////////////////////////////
struct SEND_DATA_STRUCTURE // variables to be send to another arduino
{
float temp_szk_1 ; // temperatures I need to read from RS485 units
float temp_szk_2 ;
float temp_szk_3 ;
float temp_szk_4 ;
float temp_szk_5 ;
float temp_szk_6 ;
float temp_szk_7 ;
float temp_szk_8 ;
};
struct RECEIVE_DATA_STRUCTURE
{
};
RECEIVE_DATA_STRUCTURE odbierane;
SEND_DATA_STRUCTURE wysylane;
///////////////////////////////////////////////////////////////////////////////////////////////////
void setup()
{
pinMode( RS_PIN, OUTPUT);
Serial2.begin(9600);
Serial3.begin(9600);
ETin.begin(details(odbierane), &Serial2);
ETout.begin(details(wysylane), &Serial2);
lastMillis = millis();
}
///////////////////////////////////////////////////////////////////////////////
void loop()
{
unsigned long deltaMillis = 0;
unsigned long thisMillis = millis();
if (thisMillis != lastMillis)
{
deltaMillis = thisMillis-lastMillis;
lastMillis = thisMillis;
}
timer_1 -= deltaMillis;
timer_3 -= deltaMillis;
if (timer_1 <= 0)
{
timer_1 += TIMER_INTERVAL_1;
ETout.sendData();
}
if (timer_3 <= 0)
{
timer_3 += TIMER_INTERVAL_05;
read_time ++ ; // increase read_time every 500ms
}
////////////////////////////////////////////////////////////////////////////////////
if ( read_time == 1 )
{
sendRS_1(); // send READ command to converter no. 1
}
if ( read_time == 3 )
{
sendRS_2(); // send READ command to converter no. 2
}
if ( read_time == 5 )
{
sendRS_3(); // send READ command to converter no. 3
}
if ( read_time == 7 )
{
sendRS_4(); // send READ command to converter no. 4
read_time = 0;
}
if ( read_time > 8 ) // just in case of read_time skip value of 7 .
{
read_time = 0;
}
read_rs_data(); // read everithing wat's comming from RS485 bus ( UART 3 )
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
void sendRS_1() // send a READ command to RS485 converter 1
{
while ( a != 1 )
{
a ++ ;
b = 0 ;
wezel = 1;
delayMicroseconds(200);
digitalWrite(RS_PIN, HIGH);
Serial3.write('T');
delay(2); // without about 2ms delay beetween each character, unit won't respod .
Serial3.write('0');
delay(2);
Serial3.write('0');
delay(2);
Serial3.write('\r');
delay(2);
digitalWrite(RS_PIN, LOW);
}
}
void sendRS_2() // send a READ command to RS485 converter 2
{ // delay() is used because RS485 converter needs 2ms pause beetween every char
while ( b != 1 )
{
b ++;
c = 0;
wezel = 2;
delayMicroseconds(200);
digitalWrite(RS_PIN, HIGH); // RS485 send enable
Serial3.write('T');
delay(2);
Serial3.write('0');
delay(2);
Serial3.write('2');
delay(2);
Serial3.write('\r');
delay(2);
digitalWrite(RS_PIN, LOW); // RS485 read enable
}
}
void sendRS_3() // send a READ command to RS485 converter 1
{
while ( c != 1 )
{
c ++;
d = 0 ;
wezel = 3;
delayMicroseconds(200);
digitalWrite(RS_PIN, HIGH);
Serial3.write('T');
delay(2);
Serial3.write('0');
delay(2);
Serial3.write('4');
delay(2);
Serial3.write('\r');
delay(2);
digitalWrite(RS_PIN, LOW);
}
}
void sendRS_4() // send a READ command to RS485 converter 1
{
while ( d != 1 )
{
d ++ ;
a = 0 ;
wezel = 4;
delayMicroseconds(200);
digitalWrite(RS_PIN, HIGH);
Serial3.write('T');
delay(2);
Serial3.write('0');
delay(2);
Serial3.write('6');
delay(2);
Serial3.write('\r');
delay(2);
digitalWrite(RS_PIN, LOW);
}
}
///////////////////////////////////////////////////////////////////////////////
void read_rs_data() // reading UART 3
{
while (Serial3.available() )
{
delay(4); // I've tried without delay but got the same random errors.
if ( Serial3.available() > 0 )
{
char c = Serial3.read();
if ( c != '\r' && i < 27-1)
{
input[i++] = c;
input_copy[j++] = c;
}
else
{
i = 0;
j = 0;
s1 = strtok(input, "=");
if(s1)
{
s2 = strtok(NULL, "\"" );
if(s2)
{
s3 = strtok(NULL, "T");
if(s3)
{
s4 = strtok(NULL, "=");
if(s4)
{
s5 = strtok(NULL, "C");
}
}
}
}
adr_czujnika_1 = atoi(s1 + 1);
adr_czujnika_2 = atoi(s4);
switch ( adr_czujnika_2 ) // assigning temperature values to 8 variables , depending on adress 2 of RS485 converter
{
case 1 :
wysylane.temp_szk_1 = atof(s2);
wysylane.temp_szk_2 = atof(s5);
break;
case 3 :
wysylane.temp_szk_5 = atof(s2);
wysylane.temp_szk_4 = atof(s5);
break;
case 5 :
wysylane.temp_szk_3 = atof(s2);
wysylane.temp_szk_6 = atof(s5);
break;
case 7 :
wysylane.temp_szk_7 = atof(s2);
wysylane.temp_szk_8 = atof(s5);
break;
}
///////////////////////////////////////////////////////////////////////////////////////////
failure1 = strtok(input_copy, ";"); //
failure2 = strtok(NULL, "C");
input[i] = '\0';
input_copy[j] = '\0';
}
}
}
}
void draw(void)
{
}