Send sensing data from Arduino Uno to Particle Electron

I am using an Arduino Uno to facilitate sensing data collection of a KSeries CO2 sensor, SHT30 Temperature & Humidity Sensor, and Sensirion SPS30 PM sensor. I am using the Arduino Uno because it contains libraries for all the sensors and I struggled to find compatible libraries in Particle WebIDE, hence why I am not connecting the sensors directly to the Electron. I would like to send the data from the Uno to my Particle Electron and then upload this data to a database (such as ThingSpeak). I have already successful tested sensing data from the Electron to the ThingSpeak database, but I am not sure how to go about transferring data from the Arduino Uno to the Particle Electron in terms of hardware wiring and software programming. Would I be able to use I2C and if so I should I best go about this? Are there other possible avenues?

you can really use any serial bus, UART, I2C, SPI, etc. Most use UART as it was designed specifically for transferring serial data between devices. Refer to the Serial Device OS API if you want to go this route

1 Like

Hi @jua23 ,
on top of what Erik mentioned above, please remember that some of the Electron inputs are 5v tolerant, but others aren’t.
See the docs for more info.

1 Like

Hi, thank you both for you responses. Is there an example I could follow? I took a look at the Serial Device OS API and I am still having trouble setting everything up. Do I have to connect the output pin on the Arduino to RX on the Electron or can I set any pin to be an input pin?

Hi,
I ran a few searches, on Google and on this forum.
On Google (this is the search I ran):

With I2C:

With serial:

On this forum (this is the search I ran):

I think the most promising one is the post from Rick.
The other two links above, arduino to arduino, can help you get more ideas about what needs to be done.

Good luck with your project and keep asking questions if need be.
Gustavo.
PS: feel free to fine-tune my searches if you need more inspiration material.

Hi Gus,

Thank you so much for your detailed response! I was able to follow the post from Rick and achieve the functionality I desired for my project. Now, I would like to send the data that the Electron is receiving from the UNO to a database in ThingSpeak. How can I convert the strings of serial data into floats so that I am able to send numerical data to ThingSpeak? I am sending data from 3 different sensors to the Electron, so is there a way for me to store the serial data into float variables?

how about using atof?

Using atof worked! The current issue I am experiencing now is my data getting mixed up between the 3 different sensing variables for my project (co2, temperature, humidity). In order to keep track of which serial data corresponds to which sensing data I incorporated a counter variable but I am not sure if this is the most foolproof way. I included my current code.

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

#include "Particle.h"

// Constants
// const unsigned long SEND_INTERVAL_MS = 2000;
const size_t READ_BUF_SIZE = 64;

// ThingSpeak
// Setup ThingsSpeak client
TCPClient client;
unsigned long myChannelNumber = 2036319; //Channel ID
const char *myWriteAPIKey = "NRU6YIZ91UDZCVC3"; //Channel write API key

// Forward declarations
void processBuffer();
void ThingSpeak_pub();
void publishData();

// Global variables
int counter = 1;
//unsigned long lastSend = 0;

// general variables
float temperature = 1;
float humidity = 1;
float co2_val = 1;
float strval = 0;
int field1 = 1;
int field2 = 2;
int field3 = 3;

char readBuf[READ_BUF_SIZE];
size_t readBufOffset = 0;
const char *PUBLISH_EVENT_NAME = "serial_test_1";

void setup() {
	Serial.begin(9600);
	ThingSpeak.begin(client);

	// Serial1 RX is connected to Arduino TX (1)
	// Serial2 TX is connected to Arduino RX (0)
	// Photon GND is connected to Arduino GND
	Serial1.begin(9600);
}

void loop() {
	/* if (millis() - lastSend >= SEND_INTERVAL_MS) {
		lastSend = millis();

		Serial1.printlnf("%d", ++counter);
		Serial.printlnf("Sent to Arduiuno: %d", counter);
	} */

	// Read data from serial
	while(Serial1.available()) {
		if (readBufOffset < READ_BUF_SIZE) {
			char c = Serial1.read();
			if (c != '\n') {
				// Add character to buffer
				readBuf[readBufOffset++] = c;
			}
			else {
				// End of line character found, process line
				readBuf[readBufOffset] = 0;
				processBuffer();
				readBufOffset = 0;
				counter++;
				
			}
		}
		else {
			Serial.println("readBuf overflow, emptying buffer");
			readBufOffset = 0;
		}
	}

}

void processBuffer() {
    strval = atof(readBuf);
    // Serial.println(counter);
    
    if(counter == 1){
        co2_val = strval;
        return;
    }
    else if(counter == 2){
        temperature = strval;
        return;
    }
    else {
        humidity = strval;
        Serial.println(co2_val);
        Serial.println(temperature);
        Serial.println(humidity);
        // delay(1000);
		ThingSpeak_pub();
		publishData();
		counter = 0;
		return;
    }
	// Serial.printlnf("Received from Arduino: %s", readBuf);
}

void ThingSpeak_pub() {
    // set fields one at a time
    ThingSpeak.setField(field1,co2_val);
    ThingSpeak.setField(field2,temperature);
    ThingSpeak.setField(field3,humidity);
    
    // write the fields that you've set all at once
    ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); 
    
}

void publishData() {
    
	char buf[256];
	// snprintf(buf, sizeof(buf), "{\"gpsdatalat\":%.1lf,\"gpsdatalng\":%.1lf,\"gpsalt\"co2\":%.1lf\"temperature\":%.2lf,\"humidity\":%.2lf,\}", gpsdatalat, gpsdatalng, gpsalt, co2_val,temperature,humidity);
	snprintf(buf, sizeof(buf), "{\"co2\":%.1lf\"temperature\":%.2lf,\"humidity\":%.2lf,\}",co2_val,temperature,humidity);
	Serial.println(buf);
	Particle.publish(PUBLISH_EVENT_NAME, buf, PRIVATE);
}

Hi,
What if you tagged on the arduino each value going out?
like: β€œ1:0.3”, β€œ2:25.5” and β€œ3:55”
where a simple mapping can be
1 is CO2
2 is temp
3 is humidity

Another option: send the units via serial
0.3ppm
25.5F (or C for celsius)
55%

Cheers