This post is a continuation and modified version of an earlier post from few years ago.
Please help with the Dynamic function capturing data from a Serial stream from Arduino. I am not having luck with Dynamic capture of data from an Arduino serial port. Here is my code
dev = DeviceOpen["Serial", "COM3"]
parseData[{val1__, 44, val2__, 44, val3__}] :=
ToExpression@FromCharacterCode@# & /@ {{val1}, {val2}, {val3}}
parseData[___] := Sequence[]
rawReadings = {}
task = SessionSubmit[
ScheduledTask[
AppendTo[rawReadings,
DeviceReadBuffer[dev, "ReadTerminator" -> 10]], {1, 100},
"AutoRemove" -> true]]
rawReadings
test1 = parseData /@ rawReadings
ListLinePlot[Transpose[parseData /@ rawReadings],
PlotLegends -> Automatic] // Dynamic
DeviceClose[dev]
The Arduino sketch sends a group of 3 integers separated by a coma (ASCii 44) . Sometimes when loading, the buffer does send all 3 pairs and carriage return (ASCII 10). But not sure if this is the problem.
So far, the code plots 3 or maybe 4 sets , then stops. I like to Dynamic plotting of the data stream from Arduino
The code of the Arduino sketch is below. It is a modification of the original to print 3 sensor readings.
#include <Wire.h>
#include "Adafruit_AS726x.h"
//create the object
Adafruit_AS726x ams;
//buffer para leer valores en bruto
uint16_t sensorValues[AS726x_NUM_CHANNELS];
//buffer para guardar los valores calibrados( no esta siendo utilizado en este codigo)
//float calibratedValues[AS726x_NUM_CHANNELS];
void setup() {
Serial.begin(9600);
while(!Serial);
// inicializa el pin digital LED_BUILTIN como un output.
pinMode(LED_BUILTIN, OUTPUT);
//inicia y permite la comunicacion con el sensor
if(!ams.begin()){
Serial.println("could not connect to sensor! Please check your wiring.");
while(1);
}
}
void loop() {
//lee la temperatura del sensor
uint8_t temp = ams.readTemperature();
//ams.drvOn(); // descomentar esto si quieres usar el led del sensor para hacer medidas
ams.startMeasurement(); //begin a measurement
//permite que el sensor lea la data cuando este disponible
bool rdy = false;
while(!rdy){
delay(1000);
rdy = ams.dataReady();
}
//ams.drvOff(); //descomentar esto si quieres usar el led del sensor para hacer medidas
//lee los valores!
ams.readRawValues(sensorValues);
//ams.readCalibratedValues(calibratedValues);
//Serial.print("{");
//Serial.print("Temp: ");
//Serial.print(temp);
//Serial.print(",");
//Serial.print(" Violet: ");
//Serial.print(sensorValues[AS726x_VIOLET]);
//Serial.print(",");
//Serial.print(" Blue: ");
Serial.print(sensorValues[AS726x_BLUE]);
Serial.print(",");
//Serial.print(" Green: ");
//Serial.print(sensorValues[AS726x_GREEN]);
//Serial.print(",");
//Serial.print(" Yellow: ");
Serial.print(sensorValues[AS726x_YELLOW]);
Serial.print(",");
//Serial.print(" Orange: ");
//Serial.print(sensorValues[AS726x_ORANGE]);
//Serial.print(",");
//Serial.print(" Red: ");
Serial.print(sensorValues[AS726x_RED]);
//Serial.print("}");
Serial.println();
//Serial.println();
delay(400);
}
FOLLOW-UP #2
After applying @wvt_beginner feedback and comment, the delay where removed from the Arduino Code. The reading of the stream is stabled but it serial closes after 3 or 4 data sets delivered.
Follow-up Update 2:
So, found out that the problem had nothing to do with the code, but with Mathematica. Was running version 11.2 . I first mover the rawReadings = {} line to before the parseData function. There , I noticed that the serial port pick up 7 and 8 dataset. Give me the idea that maybe potentially a problem with the compilation.
I upgraded to WM version 13.1 and the Dynamic is picking up with a continuous readings.
I am still having problemns with the serial. I ented the run with CNTL+c then restarted teh otebook. I am getting failure.
UPDATE 3
So far, I applied the option or removing and replacing teh Delay() with a timer loop. But I am getting 0 readings. It looks possibly a problem with the way the variable have been set up. Here is the updated code. BUT only returns 0 readings.
Here is the SKETCH
#include <Wire.h>
#include "Adafruit_AS726x.h"
//create the object
Adafruit_AS726x ams;
//buffer para leer valores en bruto
uint16_t sensorValues[AS726x_NUM_CHANNELS];
//buffer para guardar los valores calibrados( no esta siendo utilizado en este codigo)
//float calibratedValues[AS726x_NUM_CHANNELS];
void setup() {
Serial.begin(115200);
while (!Serial)
;
// inicializa el pin digital LED_BUILTIN como un output.
pinMode(LED_BUILTIN, OUTPUT);
//inicia y permite la comunicacion con el sensor
if (!ams.begin()) {
Serial.println("could not connect to sensor! Please check your wiring.");
while (1)
;
}
}
void loop() {
//lee la temperatura del sensor
//uint8_t temp = ams.readTemperature();
//ams.drvOn(); // descomentar esto si quieres usar el led del sensor para hacer medidas
ams.startMeasurement(); //begin a measurement
//permite que el sensor lea la data cuando este disponible
bool rdy = false;
while (!rdy) {
delay(5);
rdy = ams.dataReady();
}
//ams.drvOff(); //descomentar esto si quieres usar el led del sensor para hacer medidas
//lee los valores!
ams.readRawValues(sensorValues);
//ams.readCalibratedValues(calibratedValues);
//Serial.print("{");
//Serial.print("Temp: ");
//Serial.print(temp);
//Serial.print(",");
//Serial.print(" Violet: ");
Serial.print(sensorValues[AS726x_VIOLET]);
Serial.print(",");
//Serial.print(" Blue: ");
Serial.print(sensorValues[AS726x_BLUE]);
Serial.print(",");
//Serial.print(" Green: ");
Serial.print(sensorValues[AS726x_GREEN]);
Serial.print(",");
//Serial.print(" Yellow: ");
Serial.print(sensorValues[AS726x_YELLOW]);
Serial.print(",");
//Serial.print(" Orange: ");
Serial.print(sensorValues[AS726x_ORANGE]);
Serial.print(",");
//Serial.print(" Red: ");
Serial.print(sensorValues[AS726x_RED]);
//Serial.print("}");
Serial.println();
;
}
true
is in blue color which is an undefined quantity yet. TryTrue
instead. Also the double underscores in the function definition can match more than one input, try to use a single underscore for each. Also try the Arduino SE site for a better chance at getting this resolved. $\endgroup$rawReadings = {{50, 50, 44, 53, 53, 50, 44, 51, 54, 13}, {50, 50, 44, 53, 51, 44, 51, 54, 13}, {50, 49, 44, 53, 50, 44, 51, 54, 13}}
thenSequenceSplit[#, {44}] & /@ rawReadings
would give the desired result. $\endgroup$parseData
is trying to get values separated by the commas. This function is where the code will go as the example in my comment suggests. Please post code. Please explain howtest1
came about fromrawReadings
as I cannot see how. The second definition ofparseData
matches anything at all, so I suggest that you comment it out temporarily and check the effect of doing so. Reduce line speed or verify signal quality on Rx/Tx using a scope. Best of luck. $\endgroup$