Digital input, Processing & Firmata

Hi, I'm trying to make this sketch move by a digital input from ping))) ultrasonic sensor. No response from the sensor, like dead. Signal plugged into pin=7, ground to gnd, 5V to 5V.

I used this simple sketch (from Processing) and firmata

// Mouse movement in Y direction or ping sensor changes the position and size of the rectangle 

import processing.serial.*;
import cc.arduino.*; 
Arduino arduino; 

void setup() 
{
  size(200, 200); 
  noStroke();
  rectMode(CENTER);
  
  println(Serial.list());
  arduino = new Arduino(this, Arduino.list()[0], 57600);
  arduino.pinMode(7, Arduino.INPUT);
}

void draw() 
{   
  background(51); 
  fill(255, 204);
  rect(arduino.digitalRead(7), height/2, mouseY/2+10, mouseY/2+10);
  fill(255, 204);
  int inverseX = width-arduino.digitalRead(7);
  int inverseY = height-mouseY;
  rect(inverseX, height/2, (inverseY/2)+10, (inverseY/2)+10);
}

It used to be "mouseX", instead of "arduino.digitalRead(7)" (I want to use the ping sensor instead of mouseX).

What am I doing wrong? Is firmata declared wrongly or digital commands aren't correct?

Thanks!! M

Basically, I'd like to get Processing/arduino work with digital input.

Is firmata declared wrongly?

No.

or digital commands aren't correct?

No.

There is another possibility, and that is that you are using them incorrectly.

Look at the example for using the Ping))) sensor. Notice that it requires setting the pin mode, setting the pin HIGH for some time, then setting the pin LOW, changing the pin mode, and using pulseIn to time how long it takes to get a response, which is a function of the distance to the object than reflected the signal.

Now, which of those steps are you doing in the Processing sketch?

Thanks PaulS!

I have tried commands from the "Ping" example, but processing doesn't recognize the pulseIn command (probably because it's an Arduino command?).

However, when I go to Arduino and Processing page (http://www.arduino.cc/playground/Interfacing/Processing)

and run the given LED example, I get the sensor to flash the LED (I just alter the delay a bit). Then I added a rectangle to "draw" with a mouseY function. Although the LED on the ping))) is flashing, the sensor isn't picking up my hand movement (--> no change in the drawing).

Here is my code (simplified the previous one):

import processing.serial.*;
import cc.arduino.*;
Arduino arduino;

void setup()
{
  size(200, 200);
  noStroke();
  rectMode(CENTER);
  
  println(Serial.list()); 
  arduino = new Arduino(this, Arduino.list()[0], 57600);
  arduino.pinMode(7, Arduino.OUTPUT);
}

 void draw()
 {
   arduino.digitalWrite(7, Arduino.HIGH);
   delay(50);
   arduino.digitalWrite(7, Arduino.LOW);
   delay(20);
   
   background(51);
   fill(255, 204);
   rectMode(CENTER);
   rect(width/2,height/2, arduino.digitalRead(7), arduino.digitalRead(7));
   fill(255, 204);
  
 }

What does it mean when the LED on the sensor is flashing, but the sensor isn't emitting any signal (at least I don't know that)??

(PS: Maybe you were on the right track PaulS with the pulseIn...I just don't know how to combine Arduino commands with Processing)

Thanks!

I just don’t know how to combine Arduino commands with Processing)

Not every Arduino function is exposed in Firmata.

You could ditch Firmata, and write a sketch on the Arduino that pings and sends the distance value to the serial port, as frequently as you deem reasonable.

Then, the Processing sketch would need to test if there was serial data to read, and read it if there was.

Limiting the value sent by the Arduino to a byte (and sending the value as such) would make it very easy to read in Processing, without the need to collect characters in a string and then convert the string to an integer.

This sounds good!

I think the "Ping" example gives data, converts time to distance (which one can see ain serial monitor in Arduino IDE). If I could capture its signal and use it in Processing...hmm

A learning curve here (mostly work with Processing).

M

Limiting the value sent by the Arduino to a byte (and sending the value as such) would make it very easy to read in Processing, without the need to collect characters in a string and then convert the string to an integer.

PaulS, how would you change the Ping code, to limit the value to byte? Would you convert time to bytes?

const int pingPin = 7;

void setup() { // initialize serial communication: Serial.begin(9600); }

void loop() { // establish variables for duration of the ping, // and the distance result in inches and centimeters: long duration, inches, cm;

// The PING))) is triggered by a HIGH pulse of 2 or more microseconds. // Give a short LOW pulse beforehand to ensure a clean HIGH pulse: pinMode(pingPin, OUTPUT); digitalWrite(pingPin, LOW); delayMicroseconds(2); digitalWrite(pingPin, HIGH); delayMicroseconds(5); digitalWrite(pingPin, LOW);

// The same pin is used to read the signal from the PING))): a HIGH // pulse whose duration is the time (in microseconds) from the sending // of the ping to the reception of its echo off of an object. pinMode(pingPin, INPUT); duration = pulseIn(pingPin, HIGH);

// convert the time into a distance inches = microsecondsToInches(duration); cm = microsecondsToCentimeters(duration);

Serial.print(inches); Serial.print("in, "); Serial.print(cm); Serial.print("cm"); Serial.println();

delay(100); }

long microsecondsToInches(long microseconds) { // According to Parallax's datasheet for the PING))), there are // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per // second). This gives the distance travelled by the ping, outbound // and return, so we divide by 2 to get the distance of the obstacle. // See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf return microseconds / 74 / 2; }

long microsecondsToCentimeters(long microseconds) { // The speed of sound is 340 m/s or 29 microseconds per centimeter. // The ping travels out and back, so to find the distance of the // object we take half of the distance travelled. return microseconds / 29 / 2; }

Would you convert time to bytes

No, but maybe inches or centimetres.

Restricting inches to a max of 255 (21+ feet/7 meters) seems like a reasonable limitation to means.

Unless you have one heck of a big monitor and very long arms, that is.

Sorry, I don't understand the reasoning behind limiting the range to 7 feet. I thought I need to convert inches to bytes...

The number of inches from the sensor to the object reflecting the signal is currently stored in a long. This allows for distances of up to 2,147,483,647 inches. Which, of course is completely unreasonable, but irrelevant to the discussion.

Now, you could send the long to the serial port as 4 bytes, and then read and reassemble those bytes in Processing.

Or, you could send the long to the serial port as a string, and then read the string in Processing, and convert the string back to a long.

Or, if the reasonable limit on the distance from sensor to object that you are interested in showing in Processing WAS less than 255 inches you could just store the distance as a byte, and send (and receive) just one byte.

Any multi-byte packet needs to have error handling included to ensure that all bytes are received, and that all bytes received belong to the same packet.

If the 255 inch limit is not a problem, though, then every packet is one byte, and every byte is a complete packet, so no error handling is required.

But, if the 255 byte limit is a problem, you have options.