Arduino Values arriving differently in Processing and Arduino Serial Monitor - arduino

I have an Arduino Mega2560 which reads analog values from a sensor (Grove Loudness Sensor) and sends them to a Raspberry Pie 3b+ via USB. The values arrive perfectly and without delay in the serial monitor of the Arduino IDE. But when I try to receive them in Processing I get mostly Zeros no matter how much noise I make, with random peaks here and there.
My first guess was that my Processing code garbles the received data, so I changed the Arduino sketch to send an incrementing Integer instead of the sensor value - and those test values show correctly in Processing! Next I tried padding the sensor value in some String like "MICRO("+theSensorValue+");". The serial monitor shows the whole String and the correct sensor value, Processing shows the whole String but the value inside is still garbage..
This doesn't make any sense to me. Processing can receive any value from the Arduino correctly, except when it's the sensor value...
Arduino:
void setup() {
Serial.begin(9600);
}
void loop() {
int micLevel = analogRead(A0);
Serial.println(micLevel,DEC);
}
Processing:
Serial port;
void setup() {
port = new Serial(this, "/dev/ttyACM0", 9600);
}
void draw() {
String s = "";
if(port.available() > 0) {
s = port.readStringUntil(10);
println(s);
}
}

In Serial.println(micLevel,DEC); why are you casting the value as decimal?
Try to just Serial.println(micLevel); or convert to String if you want to send text with it Serial.println("Value is: " + String(micLevel));

Related

Processing - missing serial data from Arduino, using readStringUntil()

I've been trying to create an oscilloscope for serial data from my Arduino. In the Arduino serial plotter I can get a good waveform up to suitable frequencies, but when I try send the data to Processing it doesn't receive all the data from the Arduino. Is there a way around this?
Arduino
const int analogIn = A6;
int integratorOutput = 0;
void setup() {
// put your setup code here, to run once:
pinMode(3, OUTPUT);
pinMode(2, OUTPUT);
Serial.begin(115200);
}
void loop() {
// put your main code here, to run repeatedly:
integratorOutput = analogRead(analogIn);
Serial.println(integratorOutput);
}
Processing
void serialEvent (Serial port) {
// get the ASCII string:
String inString = port.readStringUntil('\n');
if (inString != null) {
inString = trim(inString); // trim off whitespaces.
inByte = float(inString); // convert to a number.
inByte = map(inByte, 0, 1023, 100, height-100); //map to the screen height.
println(inByte);
newData = true;
}
}
Thanks!
It's because readStringUntil is a non blocking function. Let's assume Arduino is printing a line: 12345\n The serial port at 115200 bits per seconds is relatively slow, so it's possible that the at some point the receiving buffer contains only a part of the message, for example: 1234. When the port.readStringUntil('\n') is executed it doesn't encounter a \n in the buffer so it fails and returns a NULL. You can solve this problem by using bufferUntil as in this example

Reading Data from Bluetooth using HC-05 Serial

I am having trouble reading data from the bluetooth serial interface on the Arduino.
Here my code:
#include <SoftwareSerial.h>
SoftwareSerial mySerial(8, 7); // RX, TX
void setup() {
mySerial.begin(38400);
Serial.begin(38400);
}
String Data = "";
void loop(){
//mySerial.println("Bluetooth Out");
while(mySerial.available()){
char character = mySerial.read();
Data.concat(character);
if (character == '\n'){
Serial.print("Received: ");
Serial.println(Data);
Data = "";
}
}
}
This should take whatever I enter into the bluetooth serial and print it on the regular serial port. Here is what I've tried:
If I uncomment mySerial.println("Bluetooth Out"); then I see the message bring printed out to the bluetooth terminal.
I tried similar to above to print to normal serial out and I see it being printed.
I've tried multiple ways (from some tutorials online) to decode the string and the data coming from mySerial, but nothing is happening.
I am using arduino Serial Monitor to check the ports, however I also tried to use the bluetooth terminal on my laptop and same behavior.
So I guess, what is the proper way for me to read data from the bluetooth serial port?

Issues interfacing Arduino sensor MPU6050 and Processing

I have an MPU6050 gyroscope and accelerometer connected with Arduino through the I2C protocol. These sensor send a continuos stream of data into the Serial port with these instructions (in the arduino IDE):
Serial.print(euler[0] * 180/M_PI);
Serial.print(":");
Serial.print(euler[1] * 180/M_PI);
Serial.print(":");
Serial.println(euler[2] * 180/M_PI);
This come from an example sketch included in the library of the sensor and it just sends the value of yaw / pitch / roll to the serial port, separated by the colon.
Now there is the interesting part. I've always been fascinated about visualizing data, and so i want to build a sort of graph of these data coming from serial in Processing(this is part of a larger project that include a ultrasonic sensor, like a sort of radar).
So I wrote a short sketch on processing to catch that data in order to analyze and visualize it. This is the sketch:
import processing.serial.*;
Serial myPort;
String data; //Angle values
String[] splitted; //Array containing splitted data
float yaw, pitch , roll;
void setup()
{
myPort = new Serial (this, Serial.list()[0], 115200);
}
void draw()
{
while (myPort.available() > 0) //data arrived fromm serial
{
data = myPort.readStringUntil('\n');
//Data Parsing
splitted = data.split(":");
yaw = float(splitted[0]);
pitch = float(splitted[1]);
roll = float(splitted[2]);
println(yaw + " " + pitch + " " + roll);
}
}
This code doesn't work. There are 2 errors that alternate. One of them is:
ArrayIndexOutOfBondsException
And the other one:
NullPointerException
That points to the "splitted" array.
I think i got the problem. In a previous version of the Processing sketch i was using the:
readString() function
I think that, since data are sent to the Serial port in the Arduino sketch one at a time, the processing sketch sometimes catch only one, or two of the yaw, pitch, roll values, causing the array index to crash or to a nullPointerexception when no value is added to the array. I then changed the '''readString''' to the '''readStringUntil('\n')''', because, maybe the first packet will be lost but the other one coming next will always be cathed without breaking them (i catch the entire line). But there are the same errors, so I think my small experience can't help solving the problem anymore. I need your help.
Excuse me for my bad English, and thanks for any help.
You are on the right track. Here are a few pointers:
you can use a try/catch block so the sketch doesn't simply crash on an error
you can use bufferUntil() to tell the serial library to buffer bytes for you until a new line is encountered: it works well in tandem with serialEvent() which gets called automatically (so you don't need to use a while loop that would block rendering/the rest of the sketch)
you can check (and should) anything that could go wrong with the data (null string, empty string, not enough values within the string, etc.)
Here's a modified version of your sketch:
import processing.serial.*;
Serial myPort;
float yaw, pitch , roll;
void setup()
{
String[] portNames = Serial.list();
// skipp serial setup if there are no ports
if(portNames.length == 0){
println("no serial ports found");
return;
}
// try to open serial port, handle error
try
{
myPort = new Serial (this, portNames[0], 115200);
// buffer bytes(characters) until new line is hit
myPort.bufferUntil('\n');
}
catch(Exception e)
{
println("error opening port: " + portNames[0]);
println("double check the port is present and not used by other applications (e.g. SerialMonitor)");
e.printStackTrace();
}
}
void draw()
{
background(0);
text(String.format("yaw: %.2f \npitch: %.2f \nroll: %.2f", yaw, pitch, roll), 5, 15);
}
// serialEvent gets called when there's new data: no need an explicit blocking while loop
void serialEvent(Serial port){
try
{
// read string from serial
String rawSerialString = port.readString();
// exit on null string
if(rawSerialString == null)
{
println("received null string, skipping this serial message");
return;
}
// exit on empty string
if(rawSerialString.length() == 0)
{
println("received empty string, skipping this serial message");
return;
}
// trim white space (\r, \n, etc.)
rawSerialString = rawSerialString.trim();
// split and convert to float
float[] rotations = float(rawSerialString.split(":"));
// exit if message got jumbled up and values are missing
if(rotations.length < 3)
{
println("received less than 3 values, skipping this serial message");
return;
}
// finally extract values
yaw = rotations[0];
pitch = rotations[1];
roll = rotations[2];
println(yaw + " " + pitch + " " + roll);
}
catch(Exception e)
{
println("error reading/parsing serial data");
e.printStackTrace();
}
}
Obviously you receive lines with less than two colons.
Hard to tell from here what you should do then, but checking the length of the splitted array were the first step anyway. Either via if or as an Exception.

Reading Arduino int array with Processing

I have an arduino-processing communication problem.
I have arduino code that gives me X-and/Y coordinates from a touchScreen
and it works well, no problem with that, I got my X- and Y coordinates.
BUT I need to visualize that, I am trying to write code in Processing 3.0, so that I will be able to see on my computer, where the touchFolie was being touched.
So I need to send the x-y from arduino to processing so that I will be able to draw.
Does anyone know how can I send an integer array[X,Y] from arduino to processing ??
It will be helpful to have a play with the Serial library in Processing and the SerialRead example (in Processing > File > Examples > Libraries > serial > SimpleRead)
Let's say you're starting from scratch.
To send data from Arduino you need to open a Serial connection.
At this stage the only important details is the baud rate: how fast is the data flowing.
Here's a minimal Arduino data out example:
void setup() {
//initialize the Serial library with baud rate 115200
Serial.begin(115200);
}
void loop() {
//write data to the serial port
Serial.println("test");
delay(1000);
}
If you open Serial Monitor in the Arduino software and set the baud rate to 115200 you should see test printed once a second.
To read the same data in Processing, aside from specifying the baud rate, you must also specify the serial port (what you have selected in Tools > Port and is also listed at the bottom right of your current Arduino sketch):
import processing.serial.*;
void setup() {
//update the serial port index based on your setup
println(Serial.list());
Serial arduino = new Serial(this, Serial.list()[0], 115200);
arduino.bufferUntil('\n');
}
void draw() {
}
void serialEvent(Serial p) {
//read the string from serial
String rawString = p.readString();
println(rawString);
}
Notice that we tell Processing to buffer until it reaches a '\n' character so we don't have to worry about waiting for every single character and append it manually to a String. Instead using bufferUntil(), serialEvent() and readString() most of the work is done for us.
Now that you can send a String from Arduino and read it in Processing, you can do some String manipulation, like splitting a string into multiple using a separator via the split() function:
String xyValues = "12,13";
printArray(xyValues.split(","));
The last part would be converting the split values from String to int:
String xyValues = "12,13";
String[] xy = xyValues.split(",");
printArray(xy);
int x = int(xy[0]);
int y = int(xy[1]);
println("integer values: " + x + " , " + y);
So, in theory, you should be able to do something like this on Arduino:
int x,y;
void setup() {
//initialize serial
Serial.begin(115200);
}
void loop() {
//simulating the x,y values from the touch screen,
//be sure to replace with the actual readings from
//NOTE! If the screen returns values above 255, scale them to be from 0 to 255
x = map(analogRead(A0),0,1024,0,255);
y = map(analogRead(A1),0,1024,0,255);
//write the data to serial
Serial.print(x);
Serial.print(",");
Serial.print(y);
Serial.print("\n");
}
then on the Arduino side:
import processing.serial.*;
float x,y;
void setup() {
size(400,400);
//update the serial port index based on your setup
Serial arduino = new Serial(this, Serial.list()[0], 115200);
arduino.bufferUntil('\n');
}
void draw() {
background(0);
ellipse(x,y,10,10);
}
void serialEvent(Serial p) {
//read the string from serial
String rawString = p.readString();
//trim any unwanted empty spaces
rawString = rawString.trim();
try{
//split the string into an array of 2 value (e.g. "0,127" will become ["0","127"]
String[] values = rawString.split(",");
//convert strings to int
int serialX = int(values[0]);
int serialY = int(values[1]);
//map serial values to sketch coordinates if needed
x = map(serialX,0,255,0,width);
y = map(serialY,0,255,0,height);
}catch(Exception e){
println("Error parsing string from Serial:");
e.printStackTrace();
}
}
Note The Arduino code above will probably not solve your problem as it is, you need to integrate your touch sensor code, but hopefully it provides some hints on how you can tackle this.
Sending a String, then parsing it is one approach, but not the most efficient. If you have your x,y values in a 0-255 range, you could send just 2 bytes (each coordinate as a single char) instead of up to 8 bytes, but for now it may be much easier to play with Strings rather than jump into bytes straight away.
This tutorial will help you.
5 minutes and you are able to connect each others!
EDIT:
First of all look the first part of the tutorial ("From Arduino..." "...To processing").
In arduino you have just to send your coordinates in your Serial.
Serial.println(coordX);
Serial.println(coordY);
In processing you receive this coordinates as Text but you are able to convert it in Float with parseFloat() function.
This is the code you need in Processing to receive your coordinates and store them in variables.
import processing.serial.*;
Serial myPort; // Create object from Serial class
String val; // Data received from the serial port
float x = 0;
float y = 0;
boolean first = true;
setup() {
String portName = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
myPort = new Serial(this, portName, 9600);
}
void draw() {
if ( myPort.available() > 0) { // If data is available,
val = myPort.readStringUntil('\n'); // read it and store it in val
if (first) {
x = parseFloat(val);
first = false;
println("x= "+val); //print it out in the console
}
else {
y = parseFloat(val);
first = true;
println("y= "+val); //print it out in the console
}
}
I hope this will help you solve your problem.

How to make Arduino run a script

i'm a software developer but i'm new to Arduino, and to the electronics world.
I would like to build a simple project that combined both, and really appreciate any help where to start.
final project should be Arduino with a button and a LED, when tapping the button I want run a script on my mac, then if the script finished successfully i want to turn on the LED
I already saw some tutorial about how to use buttons and LEDs so
the main thing i'm interested here is how communicate from the Arduino to the mac and vice versa. and especially how to make it run a script on my mac.
You should look into the Serial class and the examples (via File > Examples > Commmunication)
You will need to write a bit of code on the Arduino side to send data via Serial when the button is pressed (so you can trigger your script) and receive data (when the script is done) to control the LED.
Here is a rough example on the Arduino side:
const int btnPin = 12;//button pin
const int ledPin = 13;
int lastButtonState;
void setup(){
//setup pins
pinMode(btnPin,INPUT_PULLUP);
pinMode(ledPin,OUTPUT);
//setup communication
Serial.begin(9600);
}
void loop() {
int currentButtonState = digitalRead(btnPin);//read button state
if(lastButtonState != currentButtonState && currentButtonState == LOW){//if the state of the pin changed
Serial.write(currentButtonState);//send the data
lastButtonState = currentButtonState;//update the last button state
//turn on LED
digitalWrite(ledPin,HIGH);
}
}
void serialEvent(){//if any data was sent
if(Serial.available() > 0){//and there's at least 1 byte to look at
int data = Serial.read();//read the data
//do something with it if you want
//turn off the LED
digitalWrite(ledPin,LOW);
}
}
Be aware you may have different pin numbers in your setup and depending on how the button wired, you will either look for a LOW or HIGH value in the in the condition checking the currentButtonState.
In terms of the communication there are a few key elements:
Serial.begin(9600);
Starts Serial communication with baud rate 9600. You will need to match this baud rate on the other end to ensure correct communication.
Serial.write();
Will send data to the port.
serialEvent()
is predefined in Arduino and gets called when new Serial data arrives.
Note that this gets called automatically on a Arduino Uno (and other simpler boards), however this doesn't get called on other boards:
serialEvent() doesn’t work on the Leonardo, Micro, or Yún.
serialEvent() and serialEvent1() don’t work on the Arduino SAMD Boards
serialEvent(), serialEvent1()``serialEvent2(), and serialEvent3() don’t work on the Arduino Due.
On the script side, you haven't mentioned the language, but the principle is the same: you need to know the port name and baud rate to establish communication from your mac.
(You can manually call serialEvent() in loop() as a workaround. For more details see the Arduino Reference)
The port is what you used to upload the Arduino code (something like /dev/tty.usbmodem####) and in this particular case the baud rate is 9600. You should be able to test using Serial Monitor in the Arduino IDE.
Your script will be something along there lines (pseudo code)
open serial connection ( port name, baudrate = 9600 )
poll serial connection
if there is data
run the script you need
script finished executing, therefore send data back via serial connection
Be sure to checkout the Interfacing with Software to find guide on the scripting language of your choice
Update
Here's a quick example using Processing to interface with the arduino using it's Serial library. So on the Arduino side, here's a minimal sketch:
const int btnPin = 12;//button pin
const int ledPin = 13;
boolean wasPressed;
char cmd[] = "/Applications/TextEdit.app\n";
void setup(){
//setup pins
pinMode(btnPin,INPUT_PULLUP);
pinMode(ledPin,OUTPUT);
//setup communication
Serial.begin(9600);
}
void loop() {
int currentButtonState = digitalRead(btnPin);//read button state
if(!wasPressed && currentButtonState == LOW){//if the state of the pin changed
Serial.write(cmd);//send the data
wasPressed = true;//update the last button state
//turn on LED
digitalWrite(ledPin,HIGH);
}
if(currentButtonState == HIGH) wasPressed = false;
}
void serialEvent(){//if any data was sent
if(Serial.available() > 0){//and there's at least 1 byte to look at
int data = Serial.read();//read the data
//do something with it if you want
//turn off the LED
digitalWrite(ledPin,LOW);
}
}
and on the Processing side:
import processing.serial.*;
void setup(){
try{
Serial arduino = new Serial(this,"/dev/tty.usbmodemfa141",9600);
arduino.bufferUntil('\n');//buffer until a new line is encountered
}catch(Exception e){
System.err.println("Error opening serial connection! (check cables and port/baud settings!");
e.printStackTrace();
}
}
void draw(){}
void serialEvent(Serial s){
String[] command = s.readString().trim().split(",");//trim spaces, split to String[] for args
println(command);//see what we got
open(command);//run the command
s.write("A");//send a message back to flag that the command is finished (turn LED off)
}
Hope this is a helpful proof of concept. Feel free to use any other language with a serial library available instead of Processing. The syntax may differ just a tad (probably more on the running of the process/command), but the concept is the same.
Update The example above can be simplified a touch by not having the command on the Arduino side:
there's less data sent on Serial from Arduino to Processing reducing communication time and the odds of communication interference
the app runs on a computer hence changing the command is simpler to do on software side as opposed to having to change the Arduino code and re-upload each time.
Arduino:
const int btnPin = 12;//button pin
const int ledPin = 13;
boolean wasPressed;
void setup(){
//setup pins
pinMode(btnPin,INPUT_PULLUP);
pinMode(ledPin,OUTPUT);
//setup communication
Serial.begin(9600);
}
void loop() {
int currentButtonState = digitalRead(btnPin);//read button state
if(!wasPressed && currentButtonState == LOW){//if the state of the pin changed
Serial.write('R');//send the data
wasPressed = true;//update the last button state
//turn on LED
digitalWrite(ledPin,HIGH);
}
if(currentButtonState == HIGH) wasPressed = false;
}
void serialEvent(){//if any data was sent
if(Serial.available() > 0){//and there's at least 1 byte to look at
int data = Serial.read();//read the data
//do something with it if you want
//turn off the LED
digitalWrite(ledPin,LOW);
}
}
Processing:
import processing.serial.*;
String[] command = {"/Applications/TextEdit.app", "myText.txt"};
void setup() {
try {
Serial arduino = new Serial(this, "/dev/tty.usbmodemfa141", 9600);
}
catch(Exception e) {
System.err.println("Error opening serial connection! (check cables and port/baud settings!");
e.printStackTrace();
}
}
void draw() {
}
void serialEvent(Serial s) {
if (s.read() == 'R') {
launch(command);//run the command
s.write("A");//send a message back to flag that the command is finished (turn LED off)
}
}
(btw, 'R' is an arbitrary single character, can be something else as long it's the same char on both Serial send and receive sides)
Also, bare in mind launch() returns Proccess which can be useful to get more information from the software launched.
Dunno if it will help you as much as it did me but this question shows a simple example of how to use the script with a simple button in an android app
Run script with android app
Hope it helps
I found a workaround in Linux. It's a little messy but it works. I use Coolterm to capture the serial output from the arduino to a text file and I wrote a small python script that reads the file (or simply, in my case, executes the command I want if the file is not empty).

Resources