Cactus Micro r2 temperature logger

#1

Hi,

I’m trying to get the following project working on my new Cactus Micro r2:

But I can’t seem to get it working, perhaps because it was designed for r1? Do you have any pointers why this isn’t woking?

Here is the full code, offcourse SSID, PASS, PUBLIC KEY and PRIVATE KEY have been changed to my personal settings.

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

//period between posts, set at 60 seconds
#define DELAY_PERIOD 60000

//pin for the DS18B20 temperature module
#define TEMPERATURE_PIN 3

// Important!! We use pin 13 for enable esp8266  
#define WIFI_ENABLE_PIN 13

#define SSID "YOUR-WIFI-SSID"
#define PASS "YOUR-WIFI-SECRET"
#define PUBLIC_KEY "YOUR-PUBLIC-KEY-SPARKFUN"
#define PRIVATE_KEY "YOUR-PRAVATE-KEY-SPARKFUN"

#define DEBUG 0


OneWire oneWire(TEMPERATURE_PIN);
DallasTemperature sensors(&oneWire);

// use http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html 
// to find the address of your DS18B20, it will be different then this
DeviceAddress thermometer = { 0x28, 0x60, 0xB7, 0xCC, 0x04, 0x00, 0x00, 0x76 };

char serialbuffer[100];//serial buffer for request command
long nextTime;//next time in millis that the temperature read will fire
int wifiConnected = 0;

SoftwareSerial mySerial(11, 12); // rx, tx

void setup()
{
    mySerial.begin(9600);//connection to ESP8266
    Serial.begin(9600); //serial debug

    if(DEBUG) {
      while(!Serial);
    }

    pinMode(13, OUTPUT);
    digitalWrite(13, HIGH);
    delay(1000);//delay

    //set mode needed for new boards
    mySerial.println("AT+RST");
    delay(3000);//delay after mode change       
    mySerial.println("AT+CWMODE=1");
    delay(300);
    mySerial.println("AT+RST");
    delay(500);

    sensors.begin();

    nextTime = millis();//reset the timer
}

boolean connectWifi() {     
 String cmd="AT+CWJAP=\"";
 cmd+=SSID;
 cmd+="\",\"";
 cmd+=PASS;
 cmd+="\"";
 Serial.println(cmd);
 mySerial.println(cmd);
           
 for(int i = 0; i < 20; i++) {
   Serial.print(".");
   if(mySerial.find("OK"))
   {
     wifiConnected = 1;
     break;
   }
   
   delay(50);
 }
 
 Serial.println(
   wifiConnected ? 
   "OK, Connected to WiFi." :
   "Can not connect to the WiFi."
 );
 
 return wifiConnected;
}

void loop()
{

    if(!wifiConnected) {
      mySerial.println("AT");
      delay(1000);
      if(mySerial.find("OK")){
        Serial.println("Module Test: OK");
        connectWifi();
      } 
    }

    if(!wifiConnected) {
      delay(500);
      return;
    }

    //output everything from ESP8266 to the Arduino Micro Serial output
    while (mySerial.available() > 0) {
      Serial.write(mySerial.read());
    }

    //to send commands to the ESP8266 from serial monitor (ex. check IP addr)
    if (Serial.available() > 0) {
       //read from serial monitor until terminating character
       int len = Serial.readBytesUntil('\n', serialbuffer, sizeof(serialbuffer));

       //trim buffer to length of the actual message
       String message = String(serialbuffer).substring(0,len-1);
       
       Serial.println("message: " + message);

       //check to see if the incoming serial message is an AT command
       if(message.substring(0,2)=="AT"){
         //make command request
         Serial.println("COMMAND REQUEST");
         mySerial.println(message); 
       }//if not AT command, ignore
    }

    //wait for timer to expire
    if(nextTime<millis()){
      Serial.print("timer reset: ");
      Serial.println(nextTime);

      //reset timer
      nextTime = millis() + DELAY_PERIOD;
      
      //get temp
      sensors.requestTemperatures();
      //send temp
      SendTempData(sensors.getTempC(thermometer));

    }
}


//web request needs to be sent without the http for now, https still needs some working
void SendTempData(float temperature){
 char temp[10];

 Serial.print("temp: ");     
 Serial.println(temperature);

 dtostrf(temperature,1,2,temp);

 //create start command
 String startcommand = "AT+CIPSTART=\"TCP\",\"data.sparkfun.com\", 80";
 
 mySerial.println(startcommand);
 Serial.println(startcommand);
 
 //test for a start error
 if(mySerial.find("Error")){
   Serial.println("error on start");
   return;
 }
 
 //create the request command
 String sendcommand = "GET /input/"; 
 sendcommand.concat(PUBLIC_KEY);
 sendcommand.concat("?private_key=");
 sendcommand.concat(PRIVATE_KEY);
 sendcommand.concat("&temp=");
 sendcommand.concat(String(temp));
 sendcommand.concat("\r\n");
 //sendcommand.concat(" HTTP/1.0\r\n\r\n");
 
 Serial.println(sendcommand);
 
 
 //send to ESP8266
 mySerial.print("AT+CIPSEND=");
 mySerial.println(sendcommand.length());
 
 //display command in serial monitor
 Serial.print("AT+CIPSEND=");
 Serial.println(sendcommand.length());
 
 if(mySerial.find(">"))
 {
   Serial.println(">");
 }else
 {
   mySerial.println("AT+CIPCLOSE");
   Serial.println("connect timeout");
   delay(1000);
   return;
 }
 
 //Serial.print("Debug:");
 //Serial.print(sendcommand);
 mySerial.print(sendcommand);
 delay(1000);
 mySerial.println("AT+CIPCLOSE");
}
#2

Hi,

The r2 replace the software serial with hardware serial port - Serial1. So you should make a minor change for the sketch.

Just replace all mySerial to Serial1.

Please let me know if this work.

#3

I changed the firmware on the chip to Nodemcu so I’m afraid I won’t be able to test the change. But thank you for the reply.

#4

Hi
I modified the code for hardware serial using Serial1, and also modified the string to be sent according to sparkfun documentation
here is the code

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

//period between posts, set at 60 seconds
#define DELAY_PERIOD 60000

//pin for the DS18B20 temperature module
#define TEMPERATURE_PIN 3

// Important!! We use pin 13 for enable esp8266  
#define WIFI_ENABLE_PIN 13

#define SSID "xxxxxxx"
#define PASS "xxxxxxx"
#define PUBLIC_KEY "ppppppppp"
#define PRIVATE_KEY "kkkkkkkkk"

#define DEBUG 0


OneWire oneWire(TEMPERATURE_PIN);
DallasTemperature sensors(&oneWire);

// use http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html 
// to find the address of your DS18B20, it will be different then this
DeviceAddress thermometer = { 0x28, 0xFF, 0xED, 0xC9, 0x81, 0x15, 0x02, 0xB2 };

char serialbuffer[100];//serial buffer for request command
long nextTime;//next time in millis that the temperature read will fire
int wifiConnected = 0;

//SoftwareSerial Serial1(11, 12); // rx, tx

void setup()
{
Serial1.begin(9600);//connection to ESP8266
Serial.begin(9600); //serial debug

if(DEBUG) {
while(!Serial);
}

    pinMode(13, OUTPUT);
    digitalWrite(13, HIGH);
    delay(1000);//delay

    //set mode needed for new boards
    Serial1.println("AT+RST");
    delay(3000);//delay after mode change       
    Serial1.println("AT+CWMODE=1");
    delay(300);
    Serial1.println("AT+RST");
    delay(500);

    sensors.begin();

    nextTime = millis();//reset the timer
}

boolean connectWifi() {     
 String cmd="AT+CWJAP=\"";
 cmd+=SSID;
 cmd+="\",\"";
 cmd+=PASS;
 cmd+="\"";
 Serial.println(cmd);
 Serial1.println(cmd);
           
 for(int i = 0; i < 20; i++) {
   Serial.print(".");
   if(Serial1.find("OK"))
   {
     wifiConnected = 1;
     break;
   }
   
   delay(50);
 }
 
 Serial.println(
   wifiConnected ? 
   "OK, Connected to WiFi." :
   "Can not connect to the WiFi."
 );
 
 return wifiConnected;
}

void loop()
{

    if(!wifiConnected) {
      Serial1.println("AT");
      delay(1000);
      if(Serial1.find("OK")){
        Serial.println("Module Test: OK");
        connectWifi();
      } 
    }

    if(!wifiConnected) {
      delay(500);
      return;
    }

    //output everything from ESP8266 to the Arduino Micro Serial output
    while (Serial1.available() > 0) {
      Serial.write(Serial1.read());
    }

    //to send commands to the ESP8266 from serial monitor (ex. check IP addr)
    if (Serial.available() > 0) {
       //read from serial monitor until terminating character
       int len = Serial.readBytesUntil('\n', serialbuffer, sizeof(serialbuffer));

       //trim buffer to length of the actual message
       String message = String(serialbuffer).substring(0,len-1);
       
       Serial.println("message: " + message);

       //check to see if the incoming serial message is an AT command
       if(message.substring(0,2)=="AT"){
         //make command request
         Serial.println("COMMAND REQUEST");
         Serial1.println(message); 
       }//if not AT command, ignore
    }

    //wait for timer to expire
    if(nextTime<millis()){
      Serial.print("timer reset: ");
      Serial.println(nextTime);

      //reset timer
      nextTime = millis() + DELAY_PERIOD;
      
      //get temp
      sensors.requestTemperatures();
      //send temp
      SendTempData(sensors.getTempC(thermometer));

    }
}


//web request needs to be sent without the http for now, https still needs some working
void SendTempData(float temperature){
 char temp[10];

 Serial.print("temp: ");     
 Serial.println(temperature);

 dtostrf(temperature,1,2,temp);

 //create start command
 String startcommand = "AT+CIPSTART=\"TCP\",\"data.sparkfun.com\", 80";
 
 Serial1.println(startcommand);
 Serial.println(startcommand);
 
 //test for a start error
 if(Serial1.find("Error")){
   Serial.println("error on start");
   return;
 }
 
 //create the request command
 String sendcommand = "GET /input/"; 
 sendcommand.concat(PUBLIC_KEY);
 sendcommand.concat("?private_key=");
 sendcommand.concat(PRIVATE_KEY);
 sendcommand.concat("&temp=");
 sendcommand.concat(String(temp));
 //sendcommand.concat("\r\n");
 //sendcommand.concat(" HTTP/1.0\r\n\r\n");
 sendcommand.concat(" HTTP/1.1\n");
 sendcommand.concat("Host: data.sparkfun.com\n");
 sendcommand.concat("Connection: close\n\n");
 
 Serial.println(sendcommand);
 
 
 //send to ESP8266
 Serial1.print("AT+CIPSEND=");
 Serial1.println(sendcommand.length());
 
 //display command in serial monitor
 Serial.print("AT+CIPSEND=");
 Serial.println(sendcommand.length());
 
 if(Serial1.find(">"))
 {
   Serial.println(">");
 }else
 {
   //Serial1.println("AT+CIPCLOSE");
   Serial.println("connect timeout");
   delay(1000);
   return;
 }
 
 //Serial.print("Debug:");
 //Serial.print(sendcommand);
 Serial1.print(sendcommand);
 delay(1000);
 Serial1.println("AT+CIPCLOSE");
}

but I cannot send data to sparkfun

in the serial monitor what I can see is that the boards connects ok to the wifi and to the server, but then it tries to send the command lenght and it fails telling “connection timeout”

here is serial output:

Module Test: OK
AT+CWJAP="xxxxxx","xxxxxxx"
...OK, Connected to WiFi.
timer reset: 4866
temp: 23.81
AT+CIPSTART="TCP","data.sparkfun.com", 80
GET /input/ppppppppp?private_key=kkkkkkkkkk&temp=23.81 HTTP/1.1
Host: data.sparkfun.com
Connection: close


AT+CIPSEND=128
connect timeout

can you please help?
thanks
Matteo

#5

could it be that with new firmware must be specified AT+CIPMUX=0 ?
what’s the default?

#6

Please try with it.

AT+CIPMUX=0 

For better usage with REST API, I recommend flash the espduino firmware to esp8266.

Here’s the wiki.

#7

Hello
tried without multiplexing, also tried multiplexing and specifying the connection number, but no way, it always timeouts

I’ve followed the wiki and flashed espduino to ESP8266, using NodeMCUFlasher utility under windows, and flashing the two offsets (0x00000 and 0x40000), it gave green light in the end

I then flashed thingspeak.ino using a DHT11 sensor connected to pin7.
Here is the code:

/**
 * \file
 *       ESP8266 RESTful Bridge example
 * \author
 *       Tuan PM <tuanpm@live.com>
 */

#include <espduino.h>
#include <rest.h>
#include <dht.h>

#define PIN_ENABLE_ESP 13
#define SSID  "ssssssss"
#define PASS  "pppppppp"

dht DHT;
       
ESP esp(&Serial1, &Serial, 4);

REST rest(&esp);

boolean wifiConnected = false;

void wifiCb(void* response)
{
  uint32_t status;
  RESPONSE res(response);

  if(res.getArgc() == 1) {
    res.popArgs((uint8_t*)&status, 4);
    if(status == STATION_GOT_IP) {
      Serial.println("WIFI CONNECTED");
     
      wifiConnected = true;
    } else {
      wifiConnected = false;
    }
    
  }
}

void setup() {
  Serial1.begin(19200);
  Serial.begin(19200);
  esp.enable();
  delay(500);
  esp.reset();
  delay(500);
  while(!esp.ready());

  Serial.println("ARDUINO: setup rest client");
  if(!rest.begin("api.thingspeak.com/channels/69522")) {
    Serial.println("ARDUINO: failed to setup rest client");
    while(1);
  }

  /*setup wifi*/
  Serial.println("ARDUINO: setup wifi");
  esp.wifiCb.attach(&wifiCb);

  esp.wifiConnect(SSID, PASS);
  Serial.println("ARDUINO: system started");
}

void loop() {
  char response[266];
  esp.process();
  if(wifiConnected) {
    int chk = DHT.read11(7);
    if(chk == DHTLIB_OK){
      char buff[64];
      char str_hum[6], str_temp[6];
      dtostrf(DHT.humidity, 4, 2, str_hum);
      dtostrf(DHT.temperature, 4, 2, str_temp);
      sprintf(buff, "/update?api_key=Y01VVB4B2E6MP6W9&field1=%s&field2=%s", str_hum, str_temp);
      Serial.println(buff);
      rest.get((const char*)buff);
      Serial.println("ARDUINO: send get");

      if(rest.getResponse(response, 266) == HTTP_STATUS_OK){
        Serial.println("ARDUINO: GET successful");
        Serial.println(response);
      }
      delay(30000);
      
    } else {
      Serial.print("error,\r\n"); 
    }
    
    
  }
  
  
}

The code is the same as the example, I only updated SSID/PWD for wifi, channel for thingspeak and API key (this is just a test so I left them in the code)

unfortunately nothing works, thingspeak is not updated and when I open a serial monitor nothing shows up (baud is set properly at 19200), it’s all blank

the micro still works because if I flash a simple “hello world” sketch it works

please help because I’m stuck

#8

ok I got it
there is almost no documentation for espduino so I was confusing
then I looked into the library and understood that the class ESP needs the pin to enable, which is 13 for rev2 ,but in the example there was 4
also, for thingspeak GET requests, the channel must not be specified, so I removed it
now the code works

please update the examples on the github , there are also others wrong

this line

ESP esp(&Serial1, &Serial, 4);

must be instead

ESP esp(&Serial1, &Serial, PIN_ENABLE_ESP);

Matteo

#9

Thank you for your mention. Will do it right now.