I am trying to send temperature readings from one core to another. I think the correct way to do this is by using a spark variable.
The MAX 31855 board is giving me data through the spark dev serial monitor. The CLI is telling me that I have published a variable from the core in question. What’s the problem then? Well the serial data is a reasonable 24 deg C but the CLI variable data is a chilly 0 Deg C. Now I know it is winter but…
my code is as follows,
/***************************************************
This is an example for the Adafruit Thermocouple Sensor w/MAX31855K
Designed specifically to work with the Adafruit Thermocouple Sensor
----> https://www.adafruit.com/products/269
These displays use SPI to communicate, 3 pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
#include "math.h"
#include "ADAFRUIT_MAX31855.h"
int thermoCLK = A3;
int thermoCS = A2;
int thermoDO = A4;
Adafruit_MAX31855 thermocouple(thermoCLK, thermoCS, thermoDO);
double c = 0;
void setup() {
// open serial terminal and press ENTER to start
Spark.variable("temperature",&c, DOUBLE);
Serial.begin(9600);
while(!Serial.available()) SPARK_WLAN_Loop();
Serial.println("MAX31855 test");
// wait for MAX chip to stabilize
delay(500);
}
void loop() {
// basic readout test, just print the current temp
Serial.print("Internal Temp = ");
Serial.println(thermocouple.readInternal());
double c = thermocouple.readCelsius();
if (isnan(c)) {
Serial.println("Something wrong with thermocouple!");
} else {
Serial.print("C = ");
Serial.println(c);
}
//Serial.print("F = ");
//Serial.println(thermocouple.readFarenheit());
delay(1000);
}
I have not tried to pick this data up with the other core yet (I want to send it to my shiny new 16 x 32 LED matrix!)
I have been checking the process at each step by using the serial port monitor and the CLI. Looks like it is broken somewhere in the code?
When a spark variable is defined why does the second reference in brackets have an & in front of it?
BTW Merry Christmas one and all. I wished for a photon but all I got was an “I owe you” note from santa!!
Merry Christmas to you too! Your problem is that you have both a global variable "c" and a local variable "c". One you define the local variable using its type (double) with the same name, you can't see the global one any more.
Change the line above to just assign c, not define it as a double:
I bring glad tidings… You sorted it. thank you very much. Serial port and spark variable now reading the same.
To get the data to the other core should I use the subscribe command? If I have subsrribed to a data feed does that variable then become exposed to the new core. By which I mean, if I want to display the variable on a matrix display can I, after subscribing to it, just print that variable to the matrix.
I suppose I am asking if you subscribe to a spark variable in some code does that variable then become populated with the data comming to it from the cloud?
@Julian, thanks a lot and a lovely time to you too!
It’s not quite the same. Variables are retrieved when a GET “asks” for it but another Core would have to create a http-GET request to do this, which is a bit cumbersome.
On the other hand publish does push the data into the cloud actively and any subscriber can observe this and act accordingly.
But since you do get a string anyway, you can forward it to your LED matrix just as well.
I think that eventually the Spark cloud will allow core-to-core variables but for right now, the only core-to-core transfer using just the cloud is publish and subscribe.
Sometimes using both is good! You can publish a value to another core and put it in a Spark variable for a web application.
The first core is now publishing an event called, ThermoCoupleEvent. I can see the published data through the CLI by using the “spark subscribe ThermoCoupleEvent” command.
So it is the other half I am having trouble with. When I run that code it should send the variable “DATA” to the serial port, however I am not getting anything through.My questions are,
Why use an event handler subroutine? why not just have a “spark.subscribe” command?
In the event handler which of the variables are ones that should be changed to suit a particular case? In other words, my handler statement at the moment looks like this,
should I be changing the *event to *ThermoCoupleEvent?
I notice from the CLI subscribing data stream that it refers to a variable called DATA so would I be correct to assume that any information you are subscribing to come out in the subscriber code as a string called DATA?
The subscribe statement in the code for the second core is, Spark.subscribe("ThemoCoupleEvent", myHandler);
You could liken your question about Spark.subscribe() to signing an actual magazine subscription.
Would you expect having to sign and file a new subscription form for each issue of the magazine you want to have sent each week?
I guess not - and the same with Spark.subscribe(). With the magazine subscription you only give an address and you expect the magazine to hit that respective post box over and over again, without further ado.
And this post box in the Spark world is your EventHandler routine. Once the event hits the handler, it will do its job.
But your job is to define what should happen inside the handler body - you don't need to change the parameter names (as you suggested), you need to take the parameters as they are and do something with their contents.
added the above code, set the thermocouple running, checked there is data there by CLI and by a serial port monitor. Then looked on the other port for the incoming (event) and (data). Nothing is turning up.
I have tried to put the subscribe statement in the loop(); and in the setup(), it didn’t seem to make any difference, neither worked. By the way where should the subscribe statement go?
My code (the relavent bit) is now,
RGBmatrixPanel matrix(A, B, C, CLK, LAT, OE, true);
void setup() {
Serial.begin(9600);
Time.zone(0);
matrix.begin();
matrix.setTextSize(1); // size 1 == 8 pixels high
// print each letter with a rainbow color
matrix.setTextColor(matrix.Color333(4,4,4));
Spark.subscribe("ThemoCoupleEvent", myHandler);
}
As said earlier Spark.subscribe() belongs into setup()
To test if your handler gets called at all, you could do this
void myHandler(const char *event, const char *data)
{
digitalWrite(D7, !digitalRead(D7)); // blink the blue LED
Serial.println(event);
Serial.println(data);
}
void setup()
{
Spark.subscribe("ThermoCoupleEvent", myHandler);
pinMode(D7, OUTPUT); // to make the blue LED "blinkable"
Serial.begin(115200);
}
In your code above you have a typo. You are missing a r in ThermoCoupleEvent:
Please double/triple check and carefully read your code and previous posts!
@ScruffR, OK so I now have a smooth flow of data from the thermocouple through a publish command and subscribed to by another core. The receiving core is printing the data to a serial port.
When I reference the string “data” outside the handler, the code says that it is not declared in the scope. So I put the matrix.begin();, matrix.print(data); commands into the myHandler subroutine, which works a bit but the loop I have set up wipes the display, the effect of which is that the temperature flashes on and off the matrix.
Or is there some way I can expose the string “data” outside the myHandler() subroutine?
@Julian, depending on the other things you want to display there are roughly two ways to go.
If you have a lot of other data that doesn’t have anything to do with your thermo reading you’d probably go the “expose data” way, that you already suggested.
But if almost everything you want to display revolves around the temp reading, then you could consider taking all the display stuff out of loop into your event handler.
If you’d go the “expose” way you’d do something like this
char displayText[64];
void yourHandler(const char *event, cons char *data)
{
strcpy(displayText, data); // this copies the incoming string into your local buffer
}
Once you have the data in your local buffer, you can use it anywhere in your code.
If you want to go the other way, it would be good if you could show your loop() code to decide what goes and what not.