I have managed to connect the Arduino sketch to a Processing sketch, but I am stuck on how I get the Arduino to control an object in the processing.
Using a tilt sensor, the aim is that when the tilt sensor is tilted one way it will move the object in processing that way, and then when it is tilted the other way it will move the object the other way.
Can anyone help?
This is my code for Arduino:
void setup()
{
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop()
{
// put your main code here, to run repeatedly:
Serial.println("Hello, World!");
delay(100);
}
This is my code for Processing:
import processing.serial.*;
Serial myPort;
String val;
PShape bike;
void setup()
{
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
size(800, 600);
bike = createShape(RECT, 0, 0, 200, 200);
bike.setFill(color(102, 204, 0));
bike.setStroke(false);
}
void draw()
{
if ( myPort.available() > 0)
{ // If data is available,
val = myPort.readStringUntil('\n'); // read it and store it in val
}
println(val); //print it out in the console
shape(bike, 0, 0);
}
Break your problem down into smaller pieces.
Write a simple example sketch (in other words a [mcve]) that only does one thing: it simply reads in values from the Arduino and prints them to the console. It doesn't even really need to draw anything to the screen.
Write another [mcve] that just does one thing: it simply moves an object on screen. Notice that this should not involve your Arduino code at all. Try to make it as standalone as possible.
When you get both of these working completely separately, then you can think about combining them into one sketch. And if you get stuck, you can post that [mcve] along with a specific technical question.
Here's a sketch that moves an object based on the mouse position, just go get you started:
float objectX = 0;
void setup() {
size(500, 100);
}
void draw() {
if (mouseX > objectX) {
objectX ++;
}
background(0);
ellipse(objectX, height/2, 25, 25);
}
your arduino code looks that´s only hello world.
What I do to use arduino libs (sensors, actuators) using processing, is to split the tasks for 2 arduinos: one that uses the libs and send/recive data from the other arduino. This second arduino is loaded with the standard firmdata (firmware), that allows to comunicate easily and directly from processing sketch: http://playground.arduino.cc/Interfacing/Processing
Related
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
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.
I am trying to get the Qwiic Real Time Clock Module by Sparkfun working. I am using an esp8266. The clock works fine with the standard I2C pinouts, but when I change it with Wire.begin(2, 3);, it suddenly doesn't work anymore.
I've tried changing the pinouts to other examples (Wire.begin(0, 1); etc.) but nothing semes to work. I checked the wiring a ton of times and I think it is correct.
As code, I am just using a modified example written by Sparkfun.
This is my code:
void setup() {
Wire.begin(2 , 3);
Serial.begin(9600);
Serial.println("Read Time from RTC Example");
while(1) {
if (rtc.begin() == false) {
Serial.println("Something went wrong, check wiring");
} else
break;
delay(1000);
}
if (rtc.setToCompilerTime() == false) {
Serial.println("Something went wrong setting the time");
}
Serial.println("RTC online!");
}
void loop() { }
When i run the Program, it just stays in the while loop and never progresses further.
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.
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).