Arduino and Processing language
I am trying to use my Uno as a simple oscilloscope but am having a problem with processing not receiving data from the arduino.
I decided to use some simpler code from Arduino Cookbook and have simplified that even more.
Both compile and the processing code displays a white box
but no rectangle is drawn and the line: println("Message received: " + value2);
does not show up in the processing IDE message window.
When I start processing up I get a message about Sun Java but other code not using serial comms works.
Openjdk installed on my ubuntu system.
I don't know what the problem is although I have tried to find out how I can install and use the Sun java jdk
but I am completely lost with this as a lot of what I have depends on the Openjdk
and I have not been able to find out how to actually install the Sun Java sfuff anyway.
Having read various instructions I keep finding that what I have and where it is
does not correspond with the instructions.
I am running ubuntu 10.10
If I run the serial monitor in the arduino IDE I get characters displayed
so I can see the arduino code is working.
To make it as simple as possible on the hardware side all I have is a 10k pot connected +5v > one end of pot, arduino analog(0) > centre of pot, Ground > other end of pot.
Anyone any ideas as to how solve this problem please?
A couple of observations. There should be a serialEvent() method in your Processing sketch. All the serial stuff should happen in that method. It is called whenever there is serial data to process.
In that method, you can print out that you got called. You can print the number of bytes available to read. You can print each byte read from the serial port.
As it is, you don't know that Processing is even connected to the correct serial port.
Thanks Paul, I will look at that.
Just to let you know though, that the original code from 'arduino cookbook', and a similar one in 'Practical Arduino'
did not have the serialEvent() method,
I looked in the aduino IDE and it showed my board is at /dev/ttyACM0 so I substituted:
port = new Serial(this, "/dev/ttyACM0", 9600);
and it made no difference even though from the serial monitor I saw the output
/*This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/SerialEvent
*/
String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
void setup() {
// initialize serial:
Serial.begin(9600);
// reserve 200 bytes for the inputString:
inputString.reserve(200);
}
void loop() {
// print the string when a newline arrives:
if (stringComplete) {
Serial.println(inputString);
// clear the string:
inputString = "";
stringComplete = false;
}
}
/*
SerialEvent occurs whenever a new data comes in the
hardware serial RX. This routine is run between each
time loop() runs, so using delay inside loop can delay
response. Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == '\n') {
stringComplete = true;
}
}
}
import processing.serial.*;
Serial port; // Create object from Serial class
int val; // Data received from the serial port
int ypos = 0;
void setup() {
size(800, 400);
strokeWeight(2);
// IMPORTANT NOTE:
// The first serial port retrieved by Serial.list()
// should be your Arduino. If not, uncomment the next
// line by deleting the // before it. Run the sketch
// again to see a list of serial ports. Then, change
// the 0 in between [ and ] to the number of the port
// that your Arduino is connected to.
println(Serial.list());
String arduinoPort = Serial.list()[0];
port = new Serial(this, arduinoPort, 9600);
}
void draw() {
// delay(10);
if (port.available() >0) {
val = port.read();
// If data is available,
// read it and store it in val
point(ypos, val );
ypos += 1;
println(val);
}
if(ypos >799)
{
ypos=0;
background(204);
}
}
The message window in Processing prints out:
/dev/ttyACM0
which is correct
but then it just prints
52
48
52
48
over and over no matter how I adjust the potentiometer.
You are jamming data out of the Arduino pretty fast. I suggest that you add a small delay to the Arduino sketch to slow down the rate that it is sending data.
In Processing, you are assuming that each character read is the full value. That is not the case. You need to wait for the whole packet to arrive (which means that you need to define when the end of the packet has arrived).
The Arduino should use Serial.println() to send the data. Processing should use bufferUntil('\n'); to wait for all the data.
The serial data should NOT be read in draw(). It should be read, and converted to an int, in serialEvent().
int intValue;
void setup()
{
Serial.begin(9600);
}
void loop()
{
intValue = analogRead(0);
// for (int x = 0; x<200; x++)
// {
Serial.println(intValue, DEC);
delay(100);
//}
}
new processing code:
import processing.serial.*;
Serial port; // Create object from Serial class
int val; // Data received from the serial port
int ypos = 0;
void setup() {
size(800, 400);
strokeWeight(2);
println(Serial.list());
String arduinoPort = Serial.list()[0];
port = new Serial(this, arduinoPort, 9600);
port.bufferUntil('\n');
}
void draw() {
// delay(10);
println(val);
// If data is available,
// read it and store it in val
//val = map(val, 0, 320, 0, height); // Convert the value
point(ypos, val );
ypos += 1;
if(ypos >799)
{
ypos=0;
background(204);
}
//delay(10);
//rect(val/2, val, 360, val/4);
}
void SerialEvent()
{
val = int(port.read());
}
Result is just outputting 0 all the time!
Putting the line
val = int(port.read());
into the draw function produces varying values being printed
but not related to changing pot settings.
There is a serialEvent() method with a specific signature that will be called when serial data is available. If you do not override that method, the standard serialEvent() method will be called.
You can, of course, define a method with a different name or a method with a different signature, but those methods will never be called, so it is a waste of time and effort.
Sorry Paul you have lost me! As I am sure you are aware I am new to Processing. This is my first attempt at using it.
The oscilloscope program I first read about was in 'Practical Arduino' which shows the hardware and the arduino code but not the processing code. In the arduino code there is a section which alters the prescaler values to increase the speed of the analogread from 111uSec to 16uSec and the serial connection is set to 115200baud. Also there is a link to the Processing code and there is nothing in it which uses SerialEvent but it is supposed to work with the arduino code. it was that which I was originally trying to use. As I was unsuccessful I tried cutting it down and down to the bare minimum without success still
Thanks Paul,
I must have been asleep when I read your last post - blame it on my age (68).
Searched for serialEvent and realised what I needed to do so here is my code which now works in case anyone wants to use it ( for what it's worth ) under usual terms for arduino code.
arduino code
int val;
int dtime = 10;
void setup()
{
Serial.begin(115200);
}
void loop()
{
val = analogRead(0);
Serial.println(val);
delay(dtime);
}
Processing code
import processing.serial.*;
Serial myport; // Create object from Serial class
int val; // Data received from the serial port
int ypos = 0;
int xpos;
void setup() {
size(1200, 512);
strokeWeight(2);
line(0,255,1200, 255); // horizontal line half way up
String arduinoPort = Serial.list()[0];
myport = new Serial(this, arduinoPort, 115200);
myport.bufferUntil('\n');
}
void draw()
{
}
void serialEvent(Serial myport)
{
String inString = myport.readStringUntil( '\n' );
if(inString != null )
{
inString = trim(inString);
xpos = int(inString)/2;
point(ypos, 512 - xpos );
ypos += 1;
println(xpos);
if(ypos >1199) // One less than displayed window width.
{
ypos=0;
background(204);
line(0,255,1200, 255);
}
}
}