Arduino serial communication to Spark Core

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?

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.

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

Hi @random

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

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);
    }
}

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.

1 Like

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!

5 Likes

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:

3 Likes

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!

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

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?

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.

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”.

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?

I have a [Sparkfun shield][1] [1]: https://www.sparkfun.com/products/13262 that does CAN and GPS. The end-goal is to have an Electron replace the Photon that’s currently serving the development role, so I can start the vehicle, read telemetry data and (as a bonus) locate the truck if it’s ever stolen.

If I’m understanding you correctly, it seems like I’m using a drill to open a lock. I feel like I should be approaching this differently.

1 Like

If you want CAN too you might also want to talk to @jvanier who has created a Photon & Electron CAN module, formerly called CANdlestick but now being Carloop.
And maybe he can give some background on the GPS extension mentioned on their site too :wink:

1 Like

Thanks ScruffR, I’ll give it a look!

1 Like

What’s the code to communicate Spark Core back to Arduino?

Do you need that for yourself or in order to suggest a solution for Daley’s problem?

If the former, try to outline what exactly you need.
But in general the communication from Particle to Arduino works just the same as Arduino to Particle.

You can also use Carloop with the Redbear Duo if you want Bluetooth (BLE) + CAN capability. Happy to answer any questions re: Carloop as well.