Group Abstract Group Abstract

Message Boards Message Boards

Mathematica and Arduino device does not capture the serial stream under dynamic

I have set up the following sketch to capture a serial feed from an arduino. But the Dynamic command only pick up 4 feeds and dies. .

he Arduino sketch is

//*************************** // Credit original code to // Aleksandr Berezutskii //***************************

int raw1 = 0, raw2 = 0, raw3 = 0;
int x = 0, y1 = 0, y2 = 0, y3 = 0;
#define APin1 A11
#define APin2 A12
#define APin3 A13
void setup() 
{
Serial.begin(9600);
pinMode( APin1, INPUT );
pinMode( APin2, INPUT );
pinMode( APin3, INPUT );
analogReference(DEFAULT);
}

void loop() 
{
while (x<=6000)
{ 
raw1 = analogRead( APin1 );
y1=raw1;
raw2 = analogRead( APin2 );
y2=raw2;
raw3 = analogRead( APin3 );
y3=raw3;
x++;               
Serial.print( y1 );
Serial.print("\t"); 
Serial.print( y2 );
Serial.print("\t");                
Serial.print( y3 );
Serial.println();
delay(400);
}
}

The notepad is included here.

POSTED BY: Jose Calderon

It might also be useful for readers...

UART over USB is not quite robust in a way, that on the transport level the 100% delivery of all bytes is not guaranteed. I came up with a simple frame protocol to transfer with 3kHz sample rate:

int requestedSamples = -1;

void setup() {
  Serial.begin(115200);
  while (!Serial) {}
}

void loop() {
  if (requestedSamples == 0) {
     requestedSamples = -1;
     Serial.write((uint8_t)(0x0)); // Start
     return;
  }

  if (requestedSamples == -1 && Serial.available() >= 2) {
    uint8_t c0 = Serial.read(), c1 = Serial.read();
    requestedSamples = (int)c0 + (int)(c1 << 8);
    while (Serial.available() > 0) (void)Serial.read(); // clean up garbage
    Serial.write((uint8_t)(0xC0)); // End
  }

  if (requestedSamples == -1) return;

  uint16_t v = analogRead(A0);

  Serial.write((uint8_t)(((v >> 0) & 0xF)  | 0x40));
  Serial.write((uint8_t)(((v >> 4) & 0xF)  | 0x40));
  Serial.write((uint8_t)(((v >> 8) & 0xF)  | 0x40));
  Serial.write((uint8_t)(((v >> 12) & 0xF) | 0x40));

  requestedSamples--;
}

And then for WL side read the data in N-samples per request:

readDevice[dev_, packetSize_:64] := Module[{},
  If[!(DeviceOpenQ[dev]//TrueQ), Return[$Failed, Module]];

  DeviceReadBuffer[dev];
  DeviceWrite[dev, ExportByteArray[packetSize, "UnsignedInteger16"]//Normal];
  With[{result = TimeConstrained[DeviceReadBuffer[dev, packetSize 4 + 2], 0.5, $Failed]},

    If[FailureQ[result],   Return[$Failed, Module]];
    If[result[[1]] != 192, Return[$Failed, Module]];
    If[result[[-1]] != 0,  Return[$Failed, Module]];

    With[{payload = result[[2;;-2]]},
      If[Sum[BitGet[b, 6], {b, payload}] != packetSize 4, Return[$Failed, Module]];

      Map[Function[p,
        BitClear[p[[1]], 6] + BitShiftLeft[BitClear[p[[2]], 6], 4] + BitShiftLeft[BitClear[p[[3]],6], 8] + BitShiftLeft[BitClear[p[[4]],6], 12]
      ], Partition[payload, 4]]
    ]
  ]
]

Some more details are covered in a blog post there: https://wljs.io/blog/2025/08/25/analogRead

POSTED BY: Kirill Vasin
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard