I am trying to figure out how to set up serial communication between an Arduino with two sensors attached (CapSense and Ultrasonic) and openFrameworks. How can I differentiate between the two sensor input in openFrameworks?
Firmata didn’t work with CapSense, and I tried to arrange the incoming data in a “comma-separated” vector but I couldn’t make it work. Unfortunately, I don’t have that much experience with programming.
As a way of circumventing this, I have currently 2xArduinos (one for each sensor) and then just made two ofSerial objects in oF. But my readings are totally off now, I no longer understand what is going on. In openFrameworks I am constantly getting a value of 254 from the Ultrasonic, and with the CapSense I am either getting a 0 but then sometimes low 10s to 50s - with no response when I touch (usually the values are 0 to 700). But I am getting correct values in the Arduino IDE serial monitor.
My code is:
Arduino
It’s very simple code, it does what it needs to do and then I use Serial.write(exampleVariable). I use the example code from CapSense and the NewPing lib for the ultrasonic.
oF
void ofApp::setup(){
serial1.setup("COM3", 9600);
serial2.setup("COM4",9600);
}
void ofApp::update(){
if (serial1.available() < 0) {
msg = "Arduino Error";
}
else {
//While statement looping through serial messages when serial is being provided.
while (serial1.available() > 0) {
//byte data is being writen into byteData as int.
byteDataPing = serial1.readByte();
}
}
if(serial2.available() < 0) { msg = "Arduino Error"; }
else {
while (serial2.available() > 0) {
byteDataCapSense = serial2.readByte();
}
}
Can anyone help me figure out how to control the data coming from the two sensors in openFrameworks?
Any help is appreciated.
Hi,
first, are you getting the right values when you run a single sensor and use Arduino’s serial monitor?
It seems that you are printing into the serial, while on the other hand you are trying to receive data in OF and store it in a single byte, which is probably why you get 254 all the time. When you print into serial, each digit or letter you print will use a whole byte. As such, what you will usually do is to accumulate the bytes that you are getting until you get some known char that you are using to separate data, for instance a new line '\n' is quite common. Then once you get all you "decode these into an actual value. Btw bytes, chars and unsigned chars all have 8 bits, and some times are treated as the same thing.
hope this helps.
Thank you so much. I have now set it up, following the READMEs. But I am experiencing some problems:
With the PacketSerialReverseEcho.ino example it seems to be working in Arduino (correct sensor value in serial monitor), though, in oF running the cobs example, the message that is printed in the window is a fluctuating number between 0 and 900 (its not the sensor value) and then “: rebmuN emarF”. I have tried to Google it, but not been able to find out what that means. Would you have any idea what this could mean?
I also tried out the PacketSerialReverseEchoAdvanced.ino as it seems to actually be what I originally intended, “multiple PacketSerial instances and a shared handler” / I have 2 sensors connected to 1 Arduino UNO. However, with this one I am causing the SoftwareSerial to overflow as I am getting reversed ?'s in the Arduino Serial Monitor on the 9600 baud rate to which the SoftwareSerial is designated. I tested it with SoftwareSerial.overflow() and it confirmed it. You mention in the PacketSerialReverseEchoAdvanced.ino: “Failure to call the PacketSerial::update() frequently enough may result in buffer serial overflows”. I have tried to call myPacketSerial.update(); more than once, but Arduino IDE won’t compile it. Do you have any insight on how I could go about fixing this problem?
But either way, thank you for all your help so far.
It sounds like a mismatch between your Arduino code and the openFrameworks example. PacketSerialReverseEcho should not print anything intelligible to the serial console as it should be encoded. rebmuN emarF is “Frame Number” spelled backwards, meaning it’s being reversed by the arduino code. Be sure that you aren’t mixing encoded data and regular Serial.print/Serial.write commands in the Arduino code because everything that is being sent to the arduino should be encoded or else it will break the decoder on the arduino.
I think your second question may be related to the same issue with the first … if you post your Arduino code, I help clarify.
Thanks for replying so quickly. I hadn’t realised that And its because of the reversed buffer segment in the Arduino code, of course!
I used Serial.print() in the PacketSerialReverseEcho.ino code after intially running the example code to test if the sensor code was working, because I was not getting any sensor data/serialMessages through to the oF window. As I understand it, the draw() method in the cobs example should be writing the serialMessages in the window and it didn’t show anything other than ‘Frame Number: x’.
But here is the PacketSerialReverseEcho.ino code - I haven’t changed anything except deleting the reverse buffer and added the program for the ultrasonic sensor. As mentioned the only output I get in oF using the cobs example is the Frame Number, it’s not reporting any sensor values from the draw(). I don’t know why it’s not working . I think I might try and give basic ofSerial another go.
But thanks for all the help anyway!
//
// Copyright (c) 2012 Christopher Baker <https://christopherbaker.net>
//
// SPDX-License-Identifier: MIT
//
#include <PacketSerial.h>
#include <NewPing.h>
PacketSerial myPacketSerial;
/////////////////////Ping!////////////////////////////////
#define TRIGGER_PIN 11
#define ECHO_PIN 10
#define MAX_DISTANCE 500
//int for reading the distance in cm
int dist;
// NewPing setup of pins and maximum distance.
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
///////////////////////////////////////////////////////
void setup()
{
// We begin communication with our PacketSerial object by setting the
// communication speed in bits / second (baud).
myPacketSerial.begin(115200);
// If we want to receive packets, we must specify a packet handler function.
// The packet handler is a custom function with a signature like the
// onPacketReceived function below.
myPacketSerial.setPacketHandler(&onPacketReceived);
}
void loop()
{
// Do your program-specific loop() work here as usual.
dist = sonar.ping_cm();
delay(50);
// The PacketSerial::update() method attempts to read in any incoming serial
// data and emits received and decoded packets via the packet handler
// function specified by the user in the void setup() function.
//
// The PacketSerial::update() method should be called once per loop(). Failure
// to call the PacketSerial::update() frequently enough may result in buffer
// serial overflows.
myPacketSerial.update();
}
// This is our handler callback function.
// When an encoded packet is received and decoded, it will be delivered here.
// The `buffer` is a pointer to the decoded byte array. `size` is the number of
// bytes in the `buffer`.
void onPacketReceived(const uint8_t* buffer, size_t size)
{
//Just send
myPacketSerial.send(buffer, size);
}
// This function takes a byte buffer and reverses it.
void reverse(uint8_t* buffer, size_t size)
{
uint8_t tmp;
for (size_t i = 0; i < size / 2; i++)
{
tmp = buffer[i];
buffer[i] = buffer[size - i - 1];
buffer[size - i - 1] = tmp;
}
}