Arduino serial communication to Spark Core


#1

I followed this tutorial here in hopes of establishing serial communication between an Arduino Uno and Spark Core. The only difference is that I’m not using a logic level converter but a 10 k resistor. Here is my current setup:

Here is my Arduino code:

#include <SoftwareSerial.h>

SoftwareSerial ser(0,1);

void setup() {
  Serial.begin(9600);
  Serial.println("SERIAL: BEGIN");

  ser.begin(9600);
  ser.println("SOFTWARE SERIAL: BEGIN");
}


void loop() {
  if(ser.available()) {
    Serial.print("writing to serial");
    Serial.write(ser.read());
  }
}

My Spark Core code:

void setup() {
	Spark.function("sendData", sendData);

	Serial.begin(9600);
	Serial1.begin(9600);
}


void loop() {
	if(Serial1.available())
		Serial.write(Serial1.read());
}


int sendData(String command) {
	Serial.print("INCOMING: ");
	Serial.println(command);

	Serial1.print("SPARK: ");
	Serial1.println(command);

	return 1;
}

Running this the only output I receive in the sketch window is SERIAL: BEGIN.

Searching around it seems that using a 10k resister should work fine but this is the only place I could possible see this breaking. Any help is very much appreciated!


In The Interest of I2C
Communicating with the spark.io via atmel chips atmega328p, attiny, etc
Sending multiple values from Arduino Uno ATmega328 to Spark Core
#2

You setup the Software Serial on the Arduino’s Hardware Serial pins… what’s your intention here? To use Arduino Hardware Serial to receive characters, that get forwarded to a software serial output, which is hooked to Spark Serial1, which is then forwarded to Spark Serial over USB?

If so, define Software serial on D2, D3 and connect those to Serial1 of the Spark and try again :wink:

A 10k series, and 20k pull down will divide your 5V to 3.33V. So add a 20k (10k and 10k in series) pull down resistor to your Serial1 RX input to be fully legit with your voltage levels :smile:

4.7k series and 10k pull down is also good, if you have those.


#3

I am going to apologize on the front end for my amateurness and thank you for the help. Basically what I’m trying to do is send a char from the Arduino to the Spark. That link to the tutorial in my OP was the only one I could find that sent data from an Arduino to a Spark.

  1. My goal is to be able to send a char from the Arduino to the Spark.
  2. Turn the char into a string
  3. Use Spark.publish to push that string to a server and store it in a database.

I have been able to get 2 and 3 working fine. It’s just getting the data from my Arduino to the Spark that’s driving me crazy :weary: .

Here is my setup now:


My updated Arduino Code:

#include <SoftwareSerial.h>

SoftwareSerial ser(2,3);

void setup() {
  Serial.begin(9600);
  Serial.println("SERIAL: BEGIN");

  ser.begin(9600);
  ser.println("SOFTWARE SERIAL: BEGIN");
}


void loop() {
  if(ser.available()) {
    Serial.println(ser.read());
  }
}

Which this does now give me an output of:

SERIAL: BEGIN
0
0
0
0
0
0
0
0
0
0
0
0
0
0
.
.
.

EDIT:

This doesn’t really make sense to me but in the code posted above the pin settings are reversed in the Arduino code, this is the only way I can produce output. If I set them up correct with RX, TX pins correctly declared I get no output (red and white wires reversed in photo above).


#4

Basically you don’t even need to hook up the red wire as pictured above… if you are not doing any bi-directional communication (i.e. all communication is from Arduino to Spark).

You will need to swap your white and black wires in the mini breadboard though. The way you have it is 10k series and 5k pulldown, but should be the other way around.

Also SoftwareSerial ser(2, 3); // RX, TX so D3 would be the TX from the Arduino (so swap your Red/Wire wires from the picture above … just just ditch the Red wire and move White to D3).

Fingers crossed this time! :wink:

BTW: Thanks for the clear pictures! That really helps to debug.


#5

I followed your instructions and this is my new setup:

Here is my simplified down Arduino code:

#include <SoftwareSerial.h>

SoftwareSerial ser(2,3);

void setup() {
  ser.begin(9600);
}

void loop() {
  ser.write('h');
}

And here is the Spark code I’m using to take in a char and do the publish() function.

char publishString[40];


void setup() {
    
  //This works correctly and I am able to see it server side
  sprintf(publishString,"%s", "setup() began.");
  Spark.publish("Uptime",publishString);

  Serial.begin(9600);
}

void loop() {
    
    while (Serial.available() > 0)
    {
        sprintf(publishString,"%s", "We have incoming data");
        Spark.publish("Uptime",publishString);
    }
}

The first time I call Spark.publish it works and I am able to see on the server so I know that part is working. I’m still seeing no output from serial communication. Could it be because I’m outputting too much from the Arduino? That sounds weird but I guess it could be possible.

As disclosure I am a long time objective-c developer but my hardware knowledge is lacking. Spark got me excited about learning it so thank you for holding my hand.


#6

Hi @random

I don’t see a ground wire between the Arduino and Spark boards–are they powered off the same power supply? If not, you need one more wire, a ground-to-ground connection.


#7

They are not powered by the same power supply. So I need to run a ground from the Arduino to the same place (bus?) as the ground coming off the Spark?


#8

Yes! You need to connect from the GND on the Arduino (above pin 13 in your photo) to the GND on Spark (black wire in your photo.


#9

Bah thank makes so much sense.

Do you have any ideas on why the:

while (Serial.available() > 0)
    {
        sprintf(publishString,"%s", "We have incoming data");
        Spark.publish("Uptime",publishString);
    }

is never being reached in my Spark code?

Thank you for all your help


#10

Hi @random

It looks like you are using Serial on the Spark core and you should be using Serial1.


#11

I’m afraid that I am still never entering the Serial1.available() > 0 while statement. Is sending this data through serial the correct approach?

If I’m doing a SoftwareSerial out of the Arduino, is going into the RX pin on the Spark the correct method (I thought RX was hardware serial?)?

Would a better method be to go from one of the digital pins on the Arduino to one of the digital pins on the Spark? From the docs I see that the D pins can handle 5v in. That way there would be no need for any step downs.

Does that make sense or am I way out in left field :persevere:

Also, here is my updated Spark code:

char publishString[40];


void setup() {
    
    delay(1000);
  //This works correctly and I am able to see it server side
  sprintf(publishString,"%s", "setup() began.");
  Spark.publish("Uptime",publishString);

  Serial1.begin(9600);
}

void loop() {
    
    while (Serial1.available() > 0)
    {
        sprintf(publishString,"%s", "We have incoming data");
        Spark.publish("Uptime",publishString);
    }
}

#12

Hi @random

Yes, the RX pin on the Spark core is correct. You are using SoftwareSerial on the Arduino, but software serial does not currently work on Spark (there are three hardware serial ports, USB and two on the core pins instead). You have the ground wire there too, right?

You are eventually going to run into the Spark.publish() rate limit of an average of one per second with a burst of four allowed, since when it works you will publishing way too many events. You could add a delay(1000); after the ser.write(‘h’); on the Arduino side to slow it down.

I am still suspicious of your voltage divider–a real level-shifter would be a lot better.

You could try the hardware serial on the Arduino I guess–the TX pin is open right there in your photo.

I am a bit stumped.


#13

That worked!!

Thank you very much for you help @bko and @BDub.

As a recap for anyone else in the future here is my setup and code.

Hardware:

Arduino code:

#include <SoftwareSerial.h>

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.write('j');
  delay(1000);
}

Spark code:

char publishString[40];


void setup() {
    
  delay(1000);
    
  //This works correctly and I am able to see it server side
  sprintf(publishString,"%s", "setup() began.");
  Spark.publish("Uptime",publishString);

  //Fire up Serial1
  Serial1.begin(9600);
}

void loop() {
    
    while (Serial1.available() > 0)
    {
        //Print out up to server that we have had data come in
        sprintf(publishString,"%s", "We have incoming data");
        Spark.publish("Uptime",publishString);
    }
}

HTML code to display in webpage when data has been received:

<!DOCTYPE HTML>
<html>
<body>
    <span id="uptime"></span><br>
    <span id="tstamp"></span>

    <br><br>
    <button onclick="start()">Connect</button>

    <script type="text/javascript">
    function start() {

        document.getElementById("uptime").innerHTML = "Waiting for data...";
        var deviceID = "your device id";
        var accessToken = "your access token";
        var eventSource = new EventSource("https://api.spark.io/v1/devices/" + deviceID + "/events/?access_token=" + accessToken);

        eventSource.addEventListener('open', function(e) {
            console.log("Opened!"); },false);

        eventSource.addEventListener('error', function(e) {
            console.log("Errored!"); },false);

        eventSource.addEventListener('Uptime', function(e) {
            var parsedData = JSON.parse(e.data);
            var tempSpan = document.getElementById("uptime");
            var tsSpan   = document.getElementById("tstamp");
            tempSpan.innerHTML = "Core:" + parsedData.coreid + " | Data: " + parsedData.data;
            tempSpan.style.fontSize = "28px";
            tsSpan.innerHTML = "At timestamp " + parsedData.published_at;
            tsSpan.style.fontSize = "9px";
        }, false);
    }
    </script>
</body>
</html>

I hope this helps someone else in the future!


#14

Hah! Of all the things I picked up on I didn’t see that one :wink: Good catch @bko

I was doing very similar things last night with my Arduino, level shifting down to 3.3V with resistors to simulate the Spark Core, then back up to 5V using a fast buffer like the SN74HCT125N to drive a different variant of the NeoPixel strip. It was working great, but I did in fact think about the grounds at that point :smile:

Sometimes these problems are as much about what’s missing as what’s wired wrong or coded in error.

High fives everyone! :hand:


#15

Hi all,

First thank you so much for posting this, it is very helpful and I appreciate the efforts to post the working prototype after the success!

Yet I have some problems to make it work, and I can’t understand why… Help will be very much appreciated.

Several questions:

  1. The wire is connected to the TX port in the Arduino kit, correct?
  2. Which resistors did you use? 330Ohm or 10KOhm?
  3. In the Photon you connected the the wires to GND and RX, correct?

I am attaching 2 files: one of them is the only thing I can see after my HTTP request, and the other are my wiring. I will be more than glad if anyone will let me know what is wrong here???

Thank you!


#16

Unlike to its predecessor the Core on the Photon RX and TX are 5V tolerant, so you won’t need any resistors between the Arduino and Photon (providing you only ever use these pins via Serial1 and don’t set your own pinMode() for them).

The wiring should be

Arduino   Photon
GND       GND
TX        RX
RX        TX      // for good measure to talk back

--- if you don't use the USB connection for data ---
--- you could power the Photon off Arduino too   ---

+5V       Vin

#17

I’ve duplicated the working code and wiring above, and can see the output a few times in Dashboard. However, after roughly 60 seconds, the Photon begins breathing green. I’ve tried various baud rates, delays, etc. and it still results in a breathing green Photon after ~60 seconds. I also tried disconnecting the RX line (no incoming data) and always end up with the breathing green Photon.

What am I missing?


#18

What code exactly are you running?
For instance the code above contains a Spark.publish() instruction that will violate the rate limit for publishes and hence will throw off the connection after a while.


#19

Thanks for the reply ScruffR, I think you may have answered my question but I’m going to post the code as you asked - just so I’m 100% sure.

I copied/pasted the following code directly into build - which is what results in the breathing green.

char publishString[40];


void setup() {

  delay(1000);

  //This works correctly and I am able to see it server side
  sprintf(publishString,"%s", "setup() began.");
  Spark.publish("Uptime",publishString);

  //Fire up Serial1
  Serial1.begin(9600);
}

void loop() {

    while (Serial1.available() > 0)
    {
        //Print out up to server that we have had data come in
        sprintf(publishString,"%s", "We have incoming data");
        Spark.publish("Uptime",publishString); // IS THIS MY PROBLEM?
    }
}

If I’m understanding you correctly, the loop() repeats so fast that it violates the rate limit, and therefore causes me problems. Would the solution then be to put in a delay(10000); or something?

Ultimately, I’m trying to send GPS data from an Arduino UNO to the Photon. I don’t need that GPS data updated in real-time (I only need it when I need it), so maybe the more sensible solution would be to publish() only when I ask for it? If that’s the case, what should I Google for?

Again, thanks so much for the helpful response. Not looking to be spoon-fed here, but my problem is that I just don’t know what I should ask for - hence the part about “what should I Google for”.


#20

A delay(1010) (due to a “bug” 1000 is not quite enough) should do.

And to only publish on when you get data sent via Serial1 you’d need to empty the RX buffer each time you fall into your while().
As you don’t do any Serial1.read() in there the buffer will always have bytes available and hence you are never coming back out of that while() and this is your main issue.

But why exactly do you need the GPS data off the Arduino and don’t just let the Photon read the GPS module direct?