Changing modes question with SMlib

Hi,
I am currently using my loop as below (reading sensors and sending data with gsm):

void loop()
{
  if ( ( millis() - readsensorstimer ) >= readsensorsinterval )
  {
    readsensorstolcd();
    readsensorstimer += readsensorsinterval; 
  }                                                                           

  if (( millis() - gsmsendtimer ) >= gsmsendinterval )
  {
    gsmandsend();
    gsmsendtimer += gsmsendinterval; 
  }
}

I would like to have states with a pushbutton / or can be a switch button too, like:

  • when button pushed/switched - use readsensorstolcd(); than gsmandsend(); (this should be mode1)
  • when button pushed/switched again - use readsensorstolcd2(); than gsmandsend(); (this should be mode2) //here readsensorstolcd2(); would be new with different values

Maybe SMlib example 2 can be a starting point?
Your help would be appreciated, thanks!

Can you post the whole code?

I have no idea what the read sensors and gsm routines do and importantly how long they take to run.
If they are long in process then the button might not debounce cleanly every time.

In my own examples with multiple buttons (could as easily be sensors) and leds (could be motors) I am only processing 1 per pass through loop() and still get them all almost as fast as in a loop of their own. But for a tiny bit slower I have the other tasks able to run smoothly as well, the load is shared evenly.

Hi GoForSmoke,

here is the code:

//================================================LIBRARIES
#include "SIM900.h"
#include <SoftwareSerial.h>
#include "inetGSM.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>
//================================================DEFINE AND VARIABLES

// Data wire is plugged into port 3 on the Arduino
#define ONE_WIRE_BUS 3
#define TEMPERATURE_PRECISION 9
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
// arrays to hold device addresses
DeviceAddress Thermometer1, Thermometer2, Thermometer3;
//                BS  E  D4 D5  D6 D7
LiquidCrystal lcd(7, 6, 28, 26, 24, 22);

int temp1;
int temp2;
int temp3;

InetGSM inet;
char msg[50];
char buff[100];
char senddata[64];
int numdata;
char inSerial[50];
int i=0;
boolean started=false;
const int GSMOnPIN = 9; 
const int GSMresetPIN = 10;
const int ledPin =  8;

const unsigned long readsensorsinterval = 30000UL; //30 seconds
const unsigned long gsmsendinterval = 60000UL; //60 seconds

// Variable holding the timer value so far. One for each "Timer"
unsigned long readsensorstimer;
unsigned long gsmsendtimer;

//================================================SETUP

void setup()
{ 
  pinMode(GSMOnPIN, OUTPUT); 
  pinMode(GSMresetPIN, OUTPUT);  
  pinMode(ledPin, OUTPUT);
  delay(100);

  Serial.begin(19200); 
  // Start up the Sensors library
  sensors.begin();

  // locate devices on the bus
  Serial.print(F("Locating devices..."));
  Serial.print(F("Found "));
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.println(F(" devices."));

  // report parasite power requirements
  Serial.print(F("Parasite power is: ")); 
  if (sensors.isParasitePowerMode()) Serial.println(F("ON"));
  else Serial.println(F("OFF"));

  oneWire.reset_search();
  if (!oneWire.search(Thermometer1)) Serial.println(F("Unable to find address for Thermometer1"));
  if (!oneWire.search(Thermometer2)) Serial.println(F("Unable to find address for Thermometer2"));
  if (!oneWire.search(Thermometer3)) Serial.println(F("Unable to find address for Thermometer3"));
  
  // show the addresses we found on the bus
  Serial.print(F("Device 1 Address: "));
  printAddress(Thermometer1);
  Serial.println();
  Serial.print(F("Device 2 Address: "));
  printAddress(Thermometer2);
  Serial.println();
  Serial.print(F("Device 3 Address: "));
  printAddress(Thermometer3);
  Serial.println();
  

  // set the resolution to 9 bit
  sensors.setResolution(Thermometer1, TEMPERATURE_PRECISION);
  sensors.setResolution(Thermometer2, TEMPERATURE_PRECISION);
  sensors.setResolution(Thermometer3, TEMPERATURE_PRECISION);
    
  Serial.print(F("Device 1 Resolution: "));
  Serial.print(sensors.getResolution(Thermometer1), DEC); 
  Serial.println();
  Serial.print(F("Device 2 Resolution: "));
  Serial.print(sensors.getResolution(Thermometer2), DEC); 
  Serial.println();
  Serial.print(F("Device 3 Resolution: "));
  Serial.print(sensors.getResolution(Thermometer3), DEC); 
  Serial.println();
  
  readsensorstimer = millis ();
  gsmsendtimer = millis ();
 }
//================================================FUNCTIONS
void serialhwread(){
  i=0;
  if (Serial.available() > 0){            
    while (Serial.available() > 0) {
      inSerial[i]=(Serial.read());
      delay(10);
      i++;      
    }

    inSerial[i]='\0';
    if(!strcmp(inSerial,"/END")){
      Serial.println("_");
      inSerial[0]=0x1a;
      inSerial[1]='\0';
      gsm.SimpleWriteln(inSerial);
    }
    //Send a saved AT command using serial port.
    if(!strcmp(inSerial,"TEST")){
      Serial.println(F("SIGNAL QUALITY"));
      gsm.SimpleWriteln("AT+CSQ");
    }
    //Read last message saved.
    if(!strcmp(inSerial,"MSG")){
      Serial.println(msg);
    }
    else{
      Serial.println(inSerial);
      gsm.SimpleWriteln(inSerial);
    }    
    inSerial[0]='\0';
  }
}

void serialswread(){
  gsm.SimpleRead();
}

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    // zero pad the address if necessary
    if (deviceAddress[i] < 16) Serial.print(F("0"));
    Serial.print(deviceAddress[i], HEX);
  }
}
// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  Serial.print(F("Temp C: "));
  Serial.print(tempC);
}

// function to print a device's resolution
void printResolution(DeviceAddress deviceAddress)
{
  Serial.print(F("Resolution: "));
  Serial.print(sensors.getResolution(deviceAddress));
  Serial.println();    
}

// main function to print information about a device
void printData(DeviceAddress deviceAddress)
{
  Serial.print(F("Device Address: "));
  printAddress(deviceAddress);
  Serial.print(F(" "));
  printTemperature(deviceAddress);
  Serial.println();
}  

// read sensors
void readsensorstolcd(){
  //READ TEMPERATURE
  Serial.print(F("Requesting temperatures..."));
  sensors.requestTemperatures();
  Serial.println(F("DONE"));

  Serial.print(F("Temperatures are "));
  Serial.print(sensors.getTempC(Thermometer1));
  Serial.print(F(" Celsius, "));
  Serial.print(sensors.getTempC(Thermometer2));
  Serial.print(F(" Celsius, "));
  Serial.print(sensors.getTempC(Thermometer3));
  Serial.print(F(" Celsius, "));
  Serial.print(F("\n\r"));
  delay(100);
  temp1=(sensors.getTempC(Thermometer1));
  temp2=(sensors.getTempC(Thermometer2));
  temp3=(sensors.getTempC(Thermometer3));
  delay(100); 
    
  readsensorstimer = millis ();
  
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("T1:   C");
  lcd.setCursor(0, 1);
  lcd.print("T2:   C");
  lcd.setCursor(0, 2);
  lcd.print("T3:   C");
    lcd.setCursor(3, 0);
  lcd.print(temp1);
  lcd.setCursor(3, 1);
  lcd.print(temp2);
  lcd.setCursor(3, 2);
  lcd.print(temp3);
  lcd.setCursor(3, 3);
  delay(200);
} 

//GSM start,send ,stop
void gsmandsend(){

  digitalWrite(GSMOnPIN, LOW);    
  delay(3000);       
  Serial.println(F("GSM Shield starting..."));
  digitalWrite(GSMOnPIN, HIGH);   // sets the GSM on
  delay(800);                
  Serial.println(F("Its now Started"));
  digitalWrite(GSMOnPIN, LOW);
  delay(5000);

  if (gsm.begin(4800)){
    Serial.println(F("\nstatus=READY"));
    started=true;  
  }
  else Serial.println(F("\nstatus=IDLE"));
  if(started){
    if (inet.attachGPRS("***********************", "", ""))
      Serial.println(F("status=ATTACHED"));
    else Serial.println(F("status=ERROR attaching APN"));
    delay(1000);
    if (inet.connectedClient())
      digitalWrite(ledPin, HIGH);
    else
      digitalWrite(ledPin, LOW);


    //Read IP address.
    gsm.SimpleWriteln("AT+CIFSR");
    delay(5000);
    //Read until serial buffer is empty.
    gsm.WhileSimpleRead();

    // Sending data

    sprintf(senddata,"/update?key=***************************",temp1,temp2,temp3); 
    delay(500);
    numdata=inet.httpPOST("*************************", 80, senddata, buff, msg, 50);

    //Print the results.
    Serial.println(F("\nNumber data received:"));
    Serial.println(numdata);  
    Serial.println(F("\nData received:")); 
    Serial.println(msg);   
  }
  serialhwread();

  //Read for new byte on NewSoftSerial.
  serialswread(); 
  delay(800);    
  digitalWrite(GSMOnPIN, LOW);    
  delay(3000);       
  Serial.println(F("GSM Shield stopping..."));
  digitalWrite(GSMOnPIN, HIGH);   // sets the GSM off
  delay(800);                
  Serial.println(F("Its now Stopped"));
  digitalWrite(GSMOnPIN, LOW);
  gsmsendtimer = millis ();
  delay(5000);
}

//================================================LOOP

void loop()
{
  if ( ( millis() - readsensorstimer ) >= readsensorsinterval )
  {
    readsensorstolcd();
    readsensorstimer += readsensorsinterval; }

  if (( millis() - gsmsendtimer ) >= gsmsendinterval )
  {
    gsmandsend();
    gsmsendtimer += gsmsendinterval; 
  }
}

This is for testing purposes, it will be extended with more sensors. So it is now reading sensors in every 30 seconds, and sending data in every 60 seconds (what can be found in temp variables at that time will be send, thinking if it is the right way, or should I read sensors again before sending the data in gsmandsend() ).
So main goal is to read sensor values and send to lcd, and in other hand send the sensor values with gsm.

  1. If I would like to have 'independent' routines for showing data on LCD and for sending data, I should put sensor readings too to gsmandsend() routing. Is it correct?

  2. I would like to have a pushbutton to set modes for sensor readings and drive relays for example (push1 - mode1: switch relay with X temp1 sensor value ; push2-mode2: switch relay with Y temp1 value ; push3-mode1;push4-mode2 and so on) . Beside the values have to send with gsmandsend()

  3. After further tests (and learning :slight_smile: ) I would like to have lcd and button to set the temp1 values for example (but this is not important at this point.

Thanks for any help!

Too many delays to add buttons quickly.
Your code is useful but must be re-ordered and re-arranged to let button presses be noticed.

I wish you had asked more earlier before you did all this. But maybe this time you will see better.
It won't be as bad as it seems but it will be more than you thought. Probably less time that it took to write.

Once that is done then adding responsive buttons should be quick and easy but not until the delays are gone. Until then you can be pushing the buttons and holding them for many seconds with no response, because of the delays!

I really thought you understood before. No delay(). Delay blocks all code. During delay() nothing happens.

If someone convinces you to use interrupts then let me know so I can stand back and wait for the crash, the libraries you use also depend on interrupts but that doesn't stop everyone. What good is sensing a button with an interrupt if your main code is in a delayed process and won't do anything about the button press?

The parts below are as much for me as for you. I'm just trying to outline all the changes. I will need caffeine.....

The sensors need to be in arrays so they and more can be processed without adding many code lines.

DeviceAddress Thermometer[ 3 ];
int temperature[ 3 ];

The code that reads the sensors needs to be separated from the rest. It will be broken into parts.

The hardware serial read code needs to be separated and divided as above.

The gsm code also needs to be divided.

The divisions will be at every delay in the code and everywhere a part of the code takes more than a few 100 microseconds to run --- because more than one of those may happen in a row. We will break down all holdups possible and live with the rest. If a while loop takes too long, there is a fix for that.

All of those pieces will be accessed from loop but for appearances we will use inline functions to let the full source not be inside of loop() just for clarity's sake.

A number of state variables will be used to control which pieces run when.

The hardware serial read code will run as serial chars arrive and process messages as they complete.

I'm not sure what to do with the gsm read yet.

That seems to be it which means there is probably more in finding the slow gsm and 1-wire and SIM900 commands (maytherebenone), which you will have to test for more than just one quick time.

For now, I need some rest. I was already up and doing when I found your post.
I have your sketch in my Sketchbook already.

looks like a rebuilt of the code. thanks for helping me!

Let's start with hardware serial input and get that working first. I can check that part too.

I'll have that part done in a while, today.

Once that is right, each other part gets added and checked one at a time.
This how to avoid confusion over multiple bugs and effects.

We can start here with this? It runs for me but you check it.

// SIMlib mode change as event code 7-23-14 rev 0

#include <string.h>

const byte serialLen = 50;
char serialChar, serialData[ serialLen ];
byte serialCount, serialState; // default is 0

char gsmMsg[ serialLen ] = "test GSM message";


const int ledPin =  8;

//================================================SETUP

void setup( )
{ 
  pinMode( ledPin, OUTPUT );
  Serial.begin( 19200 ); 
}

//================================================FUNCTIONS

inline void hwSerialRead( )
{
  switch ( serialState )
  {
    
  case 0 :
  
    if ( Serial.available( ))
    {            
      serialChar = Serial.read( );

      if (( serialChar == '\n' ) || ( serialCount == serialLen - 1 )) // end of line 
      {
        serialState = 10; 
      }
      else
      {
        serialData[ serialCount++ ] = serialChar;
      }
    }
    break;

  case 10 : 
  
    if( !strcmp( serialData, "/END" ))
    {
      //      serialData[ 0 ] = 0x1a; // -- 0x1A is what gets sent to gsm 
      Serial.println( F( "_" )); // for now, print to monitor
    }
    //Send a saved AT command using serial port.
    else if( !strcmp( serialData, "TEST" ))
    {
      Serial.println( F( " SIGNAL QUALITY " ));
      //     gsm.SimpleWriteln("AT+CSQ");
    }
    //Read last message saved.
    else if( !strcmp( serialData, "MSG" ))
    {
      Serial.println( gsmMsg );
    }
    else
    {
      Serial.println( serialData );
      //     gsm.SimpleWriteln( serialData );
    }    

    memset( serialData, 0, serialLen );
    serialCount = 0;
    serialState = 0;

    break;
  }
}

//================================================LOOP

void loop()
{
  hwSerialRead( );
}

I have questions.

Why is serial speed 19200? Faster means serial print takes less time.

What is the source of hardware serial inputs?
I use Serial Monitor set to add newline to every line entered. If you do not then expect problem!
You can change that down next to where you set Serial Monitor speed.

So I am away from the boards, but I will back to you asap.
Serial speed: just for testing.
HW inputs: when I was trying to start and test my sim900 shield I found some information here in the forum maybe, it was one of the examples. This is working fine since months in another solution of mine with the same code.
The current hwSerialRead( ) code of yours compiled succesfully.
I will upload it and test as soon as I can!

Working on the sensor read code an I am wondering about some things.

How long does this take and would it be quicker to request and get 1 temperature at a time?

    sensors.requestTemperatures();

The answer to that will change the new sensor read code.

So first sketch : compiled successfully. After loading up and checking serial monitor, nothing can be found on the screen.
requesting temperature: I checked DS18B20 specs -> reading out is under 200ms if I'm right. And it depends maybe the lenght of the cable. Another one : SHT10 take less time. I am not a pro :slight_smile:

vespapierre:
So first sketch : compiled successfully. After loading up and checking serial monitor, nothing can be found on the screen.

That's funny, it runs for me and it will be the last step that I can run as I don't have the sensors or whatever LCD you probably have (I have a liudr 4x20 with backpack) or GSM or SIM900.

Did you make sure that serial monitor is set to the right speed and adds a newline to entries?

requesting temperature: I checked DS18B20 specs -> reading out is under 200ms if I'm right. And it depends maybe the lenght of the cable. Another one : SHT10 take less time. I am not a pro :slight_smile:

Can you set up a test sketch using the setup in your sketch and nothing in loop(), but at the end of setup put

  readsensorstimer = millis();
  sensors.requestTemperatures();
  readsensorstimer = millis() - readsensorstimer;
  Serial.print( F( "\n\n Request took: " ));
  Serial.print( readsensorstimer ));
  Serial.print( F( " ms\n" ));

I already have 100 ms waits between the request and each of the the actual reads.
Maybe 200 or more is needed but I am REALLY interested in how long just the request takes.

That bobcat, she is mean.

Sensor code added, compiles but not tested at all and needs it very much.
Can't go on without feedback and corrections which takes time.
So when you're ready, there it is.

// SIMlib mode change as event code 7-25-14 rev 0

#include <OneWire.h>
#include <DallasTemperature.h>

#include <string.h>

// user serial i/o defines
const byte serialLen = 50;
char serialChar, serialData[ serialLen ];
byte serialCount, serialState; // default of every declared variable is 0
// end user serial i/o defines

char gsmMsg[ serialLen ] = "test GSM message";

// sensor defines
// Data wire is plugged into port 3 on the Arduino
#define ONE_WIRE_BUS 3
#define TEMPERATURE_PRECISION 9
OneWire oneWire( ONE_WIRE_BUS );
DallasTemperature sensors( &oneWire );
// arrays to hold device addresses
const byte thermometers = 3;
DeviceAddress Thermometer[ thermometers ];
int temperature[ thermometers ];
unsigned long sensorsTimerStart, sensorsTimerWait;

byte  readSensorsState, readSensor;
// end sensor defines


const int ledPin =  8;

//================================================SETUP

void setup( )
{ 
  pinMode( ledPin, OUTPUT );
  Serial.begin( 115200 ); 

  // sensor setup
  // locate devices on the bus
  Serial.print( F( "Locating devices..." ));
  Serial.print( F( "Found " ));
  Serial.print( sensors.getDeviceCount(), DEC );
  Serial.println( F( " devices." ));

  // report parasite power requirements
  Serial.print( F( "Parasite power is: " )); 
  if ( sensors.isParasitePowerMode() ) 
  {
    Serial.println( F( "ON" ));
  }
  else 
  {
    Serial.println( F( "OFF" ));
  }

  oneWire.reset_search();

  byte f = 0; // this will flag if any devices are 'missing'.
  for ( byte i = 0; i < thermometers; i++ )
  {
    if (!oneWire.search( Thermometer[ i ] ))
    { 
      Serial.print( F( "Unable to find address for Thermometer " ));
      Serial.println( i );

      // BIG QUESTION HERE -- what to do about the unfound sensors?
      // Answer is stop sketch and have the user fix them.
      f = 1;
    }
    else
    {
      Serial.print( F( "Device " ));
      Serial.print( i );
      Serial.print( F( "Address: " ));
      printAddress( Thermometer[ i ] );
      Serial.println();

      // set the resolution to 9 bit
      sensors.setResolution(Thermometer[ i ], TEMPERATURE_PRECISION );
      Serial.print( F( "Device " ));
      Serial.print( i );
      Serial.print( F( " Resolution: " ));
      Serial.println( sensors.getResolution( Thermometer[ i ] ), DEC ); 
      Serial.println();
    }
  }
  if ( f )
  {
    Serial.println( "\nFix the unfound sensors please!\n" ); 
    while ( 1 ); // halts the sketch
  }
  // end sensor setup

}

//================================================FUNCTIONS

inline void hwSerialRead( )
{
  switch ( serialState )
  {

  case 0 :

    if ( Serial.available( ))
    {            
      serialChar = Serial.read( );

      if (( serialChar == '\n' ) || ( serialCount == serialLen - 1 )) // end of line 
      {
        serialState = 10; 
      }
      else
      {
        serialData[ serialCount++ ] = serialChar;
      }
    }
    break;

  case 10 : 

    if( !strcmp( serialData, "/END" ))
    {
      //      serialData[ 0 ] = 0x1a; // -- 0x1A is what gets sent to gsm 
      Serial.println( F( "_" )); // for now, print to monitor
    }
    //Send a saved AT command using serial port.
    else if( !strcmp( serialData, "TEST" ))
    {
      Serial.println( F( " SIGNAL QUALITY " ));
      //     gsm.SimpleWriteln("AT+CSQ");
    }
    //Read last message saved.
    else if( !strcmp( serialData, "MSG" ))
    {
      Serial.println( gsmMsg );
    }
    else
    {
      Serial.println( serialData );
      //     gsm.SimpleWriteln( serialData );
    }    

    memset( serialData, 0, serialLen );
    serialCount = 0;
    serialState = 0;

    break;
  }
}

// sensor functions

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    // zero pad the address if necessary
    if (deviceAddress[i] < 16) Serial.print(F("0"));
    Serial.print(deviceAddress[i], HEX);
  }
}

// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  Serial.print(F("Temp C: "));
  Serial.print(tempC);
}

// function to print a device's resolution
void printResolution(DeviceAddress deviceAddress)
{
  Serial.print(F("Resolution: "));
  Serial.print(sensors.getResolution(deviceAddress));
  Serial.println();    
}

// main function to print information about a device
void printData(DeviceAddress deviceAddress)
{
  Serial.print(F("Device Address: "));
  printAddress(deviceAddress);
  Serial.print(F(" "));
  printTemperature(deviceAddress);
  Serial.println();
}  

// read sensors
// byte  readSensorsState, readSensor;
// unsigned long sensorsTimerStart, sensorsTimerWait;

inline void readSensorsToSerial( )
{
  switch ( readSensorsState )
  {

  case 10 : // REQUEST READ TEMPERATURE 
    Serial.print( F( "Requesting temperatures..." ));
    sensorsTimerStart = millis();
    sensors.requestTemperatures(); // how long does this take???
    sensorsTimerStart = millis() - sensorsTimerStart;
    Serial.print( F( "DONE -- request ms " ));
    Serial.println( sensorsTimerStart );
    Serial.print( F("\nTemperatures are " ));
    sensorsTimerStart = millis();
    sensorsTimerWait = 100UL;
    readSensor = 0;
    readSensorsState = 20;
    break;

  case 20 : //  READ TEMPERATURE
    if ( millis() - sensorsTimerStart >= sensorsTimerWait )
    {
      temperature[ readSensor ] = ( sensors.getTempC( Thermometer[ readSensor ] ));
      Serial.print( temperature[ readSensor ] );
      Serial.print( F( " Celsius" ));
      if ( readSensor < thermometers - 1 )
      {
        Serial.print( F(", "));
        readSensor++;
      }
      else
      {
        Serial.print( F("\n\n"));
        readSensor = 0;
        //        lcd.clear();
        //        readSensorsState = 30;
        readSensorsState = 0;
      }
      sensorsTimerStart = millis();
    }
    break;

/*           uncomment when the LCD is added
  case 30 :
    if ( readSensor < thermometers )
    {
      lcd.setCursor( 0, readSensor );
      lcd.print( F( "T" ));
      lcd.print( readSensor );
      lcd.print( F( ":   C" ));
      lcd.setCursor( 3, readSensor );
      lcd.print( temp[ readSensor ] );
      readSensor++;
    }
    else
    {
      readSensor = 0;
      readSensorsState = 0;
    }
    break;
*/

  }
} 

// end sensor functions


//================================================LOOP

void loop()
{
  hwSerialRead( );
  readSensorsToSerial( );
}

ok,

so result of the sensor reading time is 96ms.
last sketch did not found devices, but tells this:

Locating devices...Found 0 devices.
Parasite power is: OFF
Device 0Address: 28FFB8DE15140085
Device 0 Resolution: 9

Device 1Address: 28FFBA3B151400CE
Device 1 Resolution: 9

Device 2Address: 28FF66CD14140062
Device 2 Resolution: 9

the startup of the sensors library left out. So added sensors.begin(); after Serial.begin( 115200 ); and :

Locating devices...Found 4 devices.
Parasite power is: OFF
Device 0Address: 28FFB8DE15140085
Device 0 Resolution: 9

Device 1Address: 28FFBA3B151400CE
Device 1 Resolution: 9

Device 2Address: 28FF66CD14140062
Device 2 Resolution: 9

note that I am just connected 4 sensor to check..no problem...
maybe with this newline I am doing something wrong...after this, no answer ... (pressed enter, entered /n, ...)

It's untested code.

Change the case 10 to case 0

inline void readSensorsToSerial( )
{
  switch ( readSensorsState )
  {

  case 10 : // REQUEST READ TEMPERATURE

Enter a bunch of random text into serial monitor.
When you enter a non-command, it prints the text. So if you don't enter a printable character, you see nothing.
Serial commands are MSG, TEST and /END. Try those.

If serial is still not working ........... add a line right after this

inline void hwSerialRead( )
{
  switch ( serialState )
  {

  case 0 :

    if ( Serial.available( ))
    {            
      serialChar = Serial.read( );
Serial.print( serialChar );

It will make a mess of the screen if hwSerialRead( ) runs and text characters are entered but it should confirm serial reads are made.

I have made a rookie's mistake, changing mode of serial monitor solved the problem, sorry!!
So it IS working! The result on serial :

Locating devices...Found 4 devices.
Parasite power is: OFF
Device 0Address: 28FFB8DE15140085
Device 0 Resolution: 9

Device 1Address: 28FFBA3B151400CE
Device 1 Resolution: 9

Device 2Address: 28FF66CD14140062
Device 2 Resolution: 9

MSG
test GSM message
/END
_
TEST
 SIGNAL QUALITY

after changing from case 10 to case 0

Locating devices...Found 4 devices.
Parasite power is: OFF
Device 0Address: 28FFB8DE15140085
Device 0 Resolution: 9

Device 1Address: 28FFBA3B151400CE
Device 1 Resolution: 9

Device 2Address: 28FF66CD14140062
Device 2 Resolution: 9

Device 3Address: 28FF69AC14140012
Device 3 Resolution: 9

Requesting temperatures...DONE -- request ms 97

Temperatures are 25 Celsius, 25 Celsius, 25 Celsius, 25 Celsius

Requesting temperatures...DONE -- request ms 96

Temperatures are 25 Celsius, 25 Celsius, 25 Celsius, 25 Celsius

Requesting temperatures...DONE -- request ms 96

Did you change the case number in readSensorsToSerial( )?

The first case in the code I posted is 10, should be 0.
There will likely be many readings fast if it works and that will get fixed.

I have modified my post, sorry :slight_smile: Yes it has been changed. So action was:

run original sketch -> got back the answer only for TEST,MSG /END

after changed case from 10 to 0 -> got back several readings

Try this:

// SIMlib mode change as event code 7-27-14 rev 1

#include <OneWire.h>
#include <DallasTemperature.h>

#include <string.h>

// user serial i/o defines
const byte serialLen = 50;
char serialChar, serialData[ serialLen ];
byte serialCount, serialState; // default of every declared variable is 0
// end user serial i/o defines

char gsmMsg[ serialLen ] = "test GSM message";

// sensor defines
// Data wire is plugged into port 3 on the Arduino
#define ONE_WIRE_BUS 3
#define TEMPERATURE_PRECISION 9
OneWire oneWire( ONE_WIRE_BUS );
DallasTemperature sensors( &oneWire );
// arrays to hold device addresses
const byte thermometers = 3;
DeviceAddress Thermometer[ thermometers ];
int temperature[ thermometers ];
unsigned long sensorsTimerStart, sensorsTimerWait;

byte  readSensorsState, readSensor;
// end sensor defines


const int ledPin =  8;

//================================================SETUP

void setup( )
{ 
  pinMode( ledPin, OUTPUT );
  Serial.begin( 115200 ); 

  // sensor setup
  sensors.begin();
  // locate devices on the bus
  Serial.print( F( "Locating devices..." ));
  Serial.print( F( "Found " ));
  Serial.print( sensors.getDeviceCount(), DEC );
  Serial.println( F( " devices." ));

  // report parasite power requirements
  Serial.print( F( "Parasite power is: " )); 
  if ( sensors.isParasitePowerMode() ) 
  {
    Serial.println( F( "ON" ));
  }
  else 
  {
    Serial.println( F( "OFF" ));
  }

  oneWire.reset_search();

  byte f = 0; // this will flag if any devices are 'missing'.
  for ( byte i = 0; i < thermometers; i++ )
  {
    if (!oneWire.search( Thermometer[ i ] ))
    { 
      Serial.print( F( "Unable to find address for Thermometer " ));
      Serial.println( i );

      // BIG QUESTION HERE -- what to do about the unfound sensors?
      // Answer is stop sketch and have the user fix them.
      f = 1;
    }
    else
    {
      Serial.print( F( "Device " ));
      Serial.print( i );
      Serial.print( F( "  Address: " ));
      printAddress( Thermometer[ i ] );
      Serial.println();

      // set the resolution to 9 bit
      sensors.setResolution(Thermometer[ i ], TEMPERATURE_PRECISION );
      Serial.print( F( "Device " ));
      Serial.print( i );
      Serial.print( F( " Resolution: " ));
      Serial.println( sensors.getResolution( Thermometer[ i ] ), DEC ); 
      Serial.println();
    }
  }
  if ( f )
  {
    Serial.println( "\nFix the unfound sensors please!\n" ); 
    while ( 1 ); // halts the sketch
  }
  // end sensor setup

  sensorsTimeStart = millis();
  sensorsTimerWait = 1000UL;

}

//================================================FUNCTIONS

inline void hwSerialRead( )
{
  switch ( serialState )
  {

  case 0 :

    if ( Serial.available( ))
    {            
      serialChar = Serial.read( );

      if (( serialChar == '\n' ) || ( serialCount == serialLen - 1 )) // end of line 
      {
        serialState = 10; 
      }
      else
      {
        serialData[ serialCount++ ] = serialChar;
      }
    }
    break;

  case 10 : 

    if( !strcmp( serialData, "/END" ))
    {
      //      serialData[ 0 ] = 0x1a; // -- 0x1A is what gets sent to gsm 
      Serial.println( F( "_" )); // for now, print to monitor
    }
    //Send a saved AT command using serial port.
    else if( !strcmp( serialData, "TEST" ))
    {
      Serial.println( F( " SIGNAL QUALITY " ));
      //     gsm.SimpleWriteln("AT+CSQ");
    }
    //Read last message saved.
    else if( !strcmp( serialData, "MSG" ))
    {
      Serial.println( gsmMsg );
    }
    else
    {
      Serial.println( serialData );
      //     gsm.SimpleWriteln( serialData );
    }    

    memset( serialData, 0, serialLen );
    serialCount = 0;
    serialState = 0;

    break;
  }
}

// sensor functions

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    // zero pad the address if necessary
    if (deviceAddress[i] < 16) Serial.print(F("0"));
    Serial.print(deviceAddress[i], HEX);
  }
}

// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  Serial.print(F("Temp C: "));
  Serial.print(tempC);
}

// function to print a device's resolution
void printResolution(DeviceAddress deviceAddress)
{
  Serial.print(F("Resolution: "));
  Serial.print(sensors.getResolution(deviceAddress));
  Serial.println();    
}

// main function to print information about a device
void printData(DeviceAddress deviceAddress)
{
  Serial.print(F("Device Address: "));
  printAddress(deviceAddress);
  Serial.print(F(" "));
  printTemperature(deviceAddress);
  Serial.println();
}  

// read sensors
// byte  readSensorsState, readSensor;
// unsigned long sensorsTimerStart, sensorsTimerWait;

inline void readSensorsToSerial( )
{
  switch ( readSensorsState )
  {

  case 0 : // REQUEST READ TEMPERATURE 
    if ( millis() - sensorsTimerStart >= sensorsTimerWait )
    {
      Serial.print( F( "Requesting temperatures..." ));
      sensorsTimerStart = millis();
      sensors.requestTemperatures(); // how long does this take???
      sensorsTimerStart = millis() - sensorsTimerStart;
      Serial.print( F( "DONE -- request ms " ));
      Serial.println( sensorsTimerStart );
      Serial.print( F("\nTemperatures are " ));
      sensorsTimerStart = millis();
      sensorsTimerWait = 100UL;
      readSensor = 0;
      readSensorsState = 20;
    }
    break;

  case 20 : //  READ TEMPERATURE
    if ( millis() - sensorsTimerStart >= sensorsTimerWait )
    {
      temperature[ readSensor ] = ( sensors.getTempC( Thermometer[ readSensor ] ));
      Serial.print( temperature[ readSensor ] );
      Serial.print( F( " Celsius" ));
      if ( readSensor < thermometers - 1 )
      {
        Serial.print( F(", "));
        readSensor++;
      }
      else
      {
        Serial.print( F("\n\n"));
        readSensor = 0;
        //        lcd.clear();
        //        readSensorsState = 30;
        readSensorsState = 0;
        sensorsTimerWait = 30000UL; // next read in 30 seconds
      }
      sensorsTimerStart = millis();
    }
    break;

    /*           uncomment when the LCD is added
     case 30 :
     if ( readSensor < thermometers )
     {
     lcd.setCursor( 0, readSensor );
     lcd.print( F( "T" ));
     lcd.print( readSensor );
     lcd.print( F( ":   C" ));
     lcd.setCursor( 3, readSensor );
     lcd.print( temp[ readSensor ] );
     readSensor++;
     }
     else
     {
     readSensor = 0;
     readSensorsState = 0;
     }
     break;
     */

  }
} 

// end sensor functions


//================================================LOOP

void loop()
{
  hwSerialRead( );
  
  if ( millis() - sensorsTimerStart >= sensorsTimerWait )
  {
    readSensorsToSerial( );
  }
}

and that is fine :slight_smile:

Locating devices...Found 4 devices.
Parasite power is: OFF
Device 0  Address: 28FFB8DE15140085
Device 0 Resolution: 9

Device 1  Address: 28FFBA3B151400CE
Device 1 Resolution: 9

Device 2  Address: 28FF66CD14140062
Device 2 Resolution: 9

Requesting temperatures...DONE -- request ms 96

Temperatures are 25 Celsius, 25 Celsius, 25 Celsius

Requesting temperatures...DONE -- request ms 96

Temperatures are 25 Celsius, 25 Celsius, 25 Celsius

Requesting temperatures...DONE -- request ms 96

Temperatures are 25 Celsius, 25 Celsius, 25 Celsius

made a correction from sensorsTimeStart = millis(); to sensorsTimerStart = millis();

I updated the change to my copy, also moved Address back 1 space.

The sensor reads are happening 30 seconds apart now?

If so and no other issues there is GSM and LCD parts and then buttons and more sensors?
I am not ready to dive into those right now.
Maybe the sketch needs a long run test anyway just to make sure there is no "down the road" bug(s).

Do you see how I got rid of the delays, using state machines and time checks?

The sensor requests take almost 1/10th second. If all they do is hold up noticing a button or serial then I don't think it's a big deal, much as I don't like it on principle. Maybe the library needs a state machine and time or other check, like answer on the 1-wire bus, too.

Yes, readings are in every 30 seconds.
Yes, those should fine as next steps ( LCD, GSM and sensors).
It is running now and will let it run for at least couple of hours.
This is nice without the delays, learning this kind is really useful.
In case there are 4 sensors attached and the code has defined as 3, than reading will up to 753ms.