Reading strings from 4 RS485 devices and parsing to 8 float variables.

Dear All :slight_smile:

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 :wink: 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 :

#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)
{

}