Thingspeak breaks Serial1?

Hi erveryone,

I’m trying to connect a K30 CO2 sensor to a Photon and get the data into Thingspeak. I’ve already got one unit working through I2C but this is a bit unstable. So I was trying to connect the sensor to the Photon through the serial port: Serial1. The strange thing is that as soon as I include and activate Thingspeak in the code it breaks the program (I get SOS flashing). Vice versa same result (Thingspeak alone works, but SOS flashing as soon as I put Serial1.begin(9600) in the setup function).
Is there some timing thing in the Thingspeak library which breaks Serial1? Normal serial (‘Serial’) works.

Thanks!

Hi @Corneel

Thingspeak uses a macro definition to control debug message but they go to Serial, not Serial1:

#ifdef PRINT_DEBUG_MESSAGES
		Serial.print("ts::tsBegin    (client: Client IP: "); Serial.print(customIP); Serial.println(")");
#endif

You could do #undef PRINT_DEBUG_MESSAGES before the #include for the Thingspeak library to be sure.

Which SOS flash are you seeing? The pattern is SOS, N-flashes, SOS, where the number of flashes tells you the error type.

Does your CO2 sensor use interrupts?

Can you post your code?

Hi @bko,

Thanks for your reply. I don’t think the sensor uses interrupts, just simple communication.
Here’s the code. I modified it slightly from the original, written for the Arduino. But I did some tests with the Thingspeak examples, and as soon as you add Serial1.begin(9600) you get the SOS.
The SOS-code is 1 blink, after the SOS, so a Hard Fault.

   // This #include statement was automatically added by the Particle IDE.
#include "ThingSpeak/ThingSpeak.h"


/*
  Basic rduino example for K-Series sensor
  Created by Jason Berger
  Co2meter.com

  Modified for the Particle Photon by Corneel Canters
*/


TCPClient client;

unsigned long myChannelNumber = ******;
const char * myWriteAPIKey = "xxxxxxxxxxxxxx";


byte readCO2[] = {0xFE, 0X44, 0X00, 0X08, 0X02, 0X9F, 0X25};  //Command packet to read Co2 (see app note)
byte response[] = {0, 0, 0, 0, 0, 0, 0}; //create an array to store the response

//multiplier for value. default is 1. set to 3 for K-30 3% and 10 for K-33 ICB
int valMultiplier = 1;

long co2Value = 0; //

int ts_loop = 0; // variable for counting number of loops so value only sent once every 20 seconds to Thingspeak


void setup()
{
  Particle.variable("ppm2", co2Value); // container for viewing value directly
  Serial1.begin(9600);         //Opens the serial port to communicate with the co2 sensor
  ThingSpeak.begin(client);
}


void loop()
{
  sendRequest(readCO2);
  unsigned long valCO2 = getValue(response);
  co2Value = int(valCO2);

  delay(2000); // 2 second delay. CO2 sensor takes new reading every 2 seconds

  if (ts_loop == 0) {
    ThingSpeak.writeField(myChannelNumber, 1, 400, myWriteAPIKey); // writ evalue to Thingspeak
  }

  if (ts_loop >= 10) // after 20 seconds reset
    ts_loop = 0;
  else
    ts_loop++;


}

void sendRequest(byte packet[])
{
  while (!Serial1.available()) //keep sending request until we start to get a response
  {
    Serial1.write(readCO2, 7);
    delay(50);
  }

  int timeout = 0; //set a timeoute counter
  while (Serial1.available() < 7 ) //Wait to get a 7 byte response
  {
    timeout++;
    if (timeout > 10)   //if it takes to long there was probably an error
    {
      while (Serial1.available()) //flush whatever we have
        Serial1.read();

      break;                        //exit and try again
    }
    delay(50);
  }

  for (int i = 0; i < 7; i++)
  {
    response[i] = Serial1.read();
  }
}


unsigned long getValue(byte packet[])
{
  int high = packet[3];                        //high byte for value is 4th byte in packet in the packet
  int low = packet[4];                         //low byte for value is 5th byte in the packet


  unsigned long val = high * 256 + low;              //Combine high byte and low byte with this formula to get value
  return val * valMultiplier;
}