Go Down

Topic: RESOLVED Send PWM data from Arduino to Processing with FIRMATA library (Read 433 times) previous topic - next topic

bvking

Hi everyones,

I would like just to know the way to send the PWM value (not only HIGH or LOW) from Arduino to Processing?

For now I can use analog input  Arduino to control Processing with FIRMATA library.

With this way, I can manage the interface in Processing where I can see ellipse move with data of analog input (programmed as analogRead) but I can't manage to control an other ellipse with the PWM value (programmed as analogWrite).

How can I say to the program, that analogWrite value can be like an analogRead value?

Thanks in advance.

I put //************************************* to see where I added code

First the Arduino Program:

Code: [Select]


/*
 * Firmata is a generic protocol for communicating with microcontrollers
 * from software on a host computer. It is intended to work with
 * any host computer software package.
 *
 * To download a host software package, please click on the following link
 * to open the download page in your default browser.
 *
 * http://firmata.org/wiki/Download
 */

/* Supports as many analog inputs and analog PWM outputs as possible.
 *
 * This example code is in the public domain.
 */
#include <Firmata.h>

//*************************************
int a=0;
int sensorPin = A0;    // select the input pin for the potentiometer
int ledPin = 9;      // pin 9 with PWM
int sensorValue = 0;  // variable to store the value coming from the sensor
int ledPin2 = 11; //  pin 11 with PWM
//****************************************

byte analogPin = 0;

void analogWriteCallback(byte pin, int value)
{
  if (IS_PIN_PWM(pin)) {
    pinMode(PIN_TO_DIGITAL(pin), OUTPUT);
    analogWrite(PIN_TO_PWM(pin), value);
 
  }
}

void setup()
{
  Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);
  Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
  Firmata.begin(57600);
 
  pinMode(ledPin, OUTPUT);
  pinMode (ledPin2, OUTPUT);
}

void loop()
{
  while (Firmata.available()) {
    Firmata.processInput();
  }
  // do one analogRead per loop, so if PC is sending a lot of
  // analog write messages, we will only delay 1 analogRead
  Firmata.sendAnalog(analogPin, analogRead(analogPin));
  analogPin = analogPin + 1;
  if (analogPin >= TOTAL_ANALOG_PINS) analogPin = 0;

//*************************************
   a=a+1;
  float b = a/100;
   int sensorValue = analogRead(A0);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5/ 1023.0);
  // print out the value you read:
  //int phi= sensorValue *

  int phi= map (voltage, 0, 5, 0, 180);
   
  analogWrite (ledPin, abs (100*cos (2*PI*b/10)));
  analogWrite (ledPin2, abs (100*cos (2*PI*b/10- phi)));

  Serial.println (b);
  Serial.println (phi);
  Serial.print ("fonction cos "); Serial.println(abs (100*cos (2*PI*b/100)));
  Serial.print ("fonction lag "); Serial.println(abs (100*cos (2*PI*b/100- phi)));
//****************************************
}


Second: Processing program

Code: [Select]

/*
arduino_input

Demonstrates the reading of digital and analog pins of an Arduino board
running the StandardFirmata firmware.

To use:
* Using the Arduino software, upload the StandardFirmata example (located
  in Examples > Firmata > StandardFirmata) to your Arduino board.
* Run this sketch and look at the list of serial ports printed in the
  message area below. Note the index of the port corresponding to your
  Arduino board (the numbering starts at 0).  (Unless your Arduino board
  happens to be at index 0 in the list, the sketch probably won't work.
  Stop it and proceed with the instructions.)
* Modify the "arduino = new Arduino(...)" line below, changing the number
  in Arduino.list()[0] to the number corresponding to the serial port of
  your Arduino board.  Alternatively, you can replace Arduino.list()[0]
  with the name of the serial port, in double quotes, e.g. "COM5" on Windows
  or "/dev/tty.usbmodem621" on Mac.
* Run this sketch. The squares show the values of the digital inputs (HIGH
  pins are filled, LOW pins are not). The circles show the values of the
  analog inputs (the bigger the circle, the higher the reading on the
  corresponding analog input pin). The pins are laid out as if the Arduino
  were held with the logo upright (i.e. pin 13 is at the upper left). Note
  that the readings from unconnected pins will fluctuate randomly.
 
For more information, see: http://playground.arduino.cc/Interfacing/Processing
*/

import processing.serial.*;

import cc.arduino.*;

Arduino arduino;

color off = color(4, 79, 111);
color on = color(84, 145, 158);

void setup() {
  size(470, 280);

  // Prints out the available serial ports.
  println(Arduino.list());
 
  // Modify this line, by changing the "0" to the index of the serial
  // port corresponding to your Arduino board (as it appears in the list
  // printed by the line above).
  //arduino = new Arduino(this, Arduino.list()[0], 57600);
 
  // Alternatively, use the name of the serial port corresponding to your
  // Arduino (in double-quotes), as in the following line.
  //arduino = new Arduino(this, "dev/tty.usbmodem1421", 57600);
 
  arduino = new Arduino(this, Serial.list()[4], 57600);
  ///dev/tty.usbmodem1421, 57600
 
  // Set the Arduino digital pins as inputs.
  for (int i = 0; i <= 13; i++)
    arduino.pinMode(i, Arduino.INPUT);
}

void draw() {
  background(off);
  stroke(on);
 
  // Draw a filled box for each digital pin that's HIGH (5 volts).
  for (int i = 0; i <= 13; i++) {
    if (arduino.digitalRead(i) == Arduino.HIGH)
      fill(on);
    else
      fill(off);
     
    rect(420 - i * 30, 30, 20, 20);
  }

  // Draw a circle whose size corresponds to the value of an analog input.
  noFill();
//********
  for (int i = 0; i <= 13; i++) { //****before i <= 5, because the 5 analog input
    ellipse( i * 30, 240, arduino.analogRead(i) / 16, arduino.analogRead(i) / 16);
  }
}


pert

Please don't cross post.

http://forum.arduino.cc/index.php?topic=604177

Duplicate posts can waste the time of the people trying to help. Someone might spend 15 minutes writing a detailed answer on this thread, without knowing that someone else already did the same in the other thread.

In the future, take some time to pick the forum section that best suits the topic of your question and then only post once to that forum section. This is basic forum etiquette, as explained in the sticky "How to use this forum - please read." post you will find at the top of every forum section. It contains a lot of other useful information. Please read it.

PaulS

Code: [Select]
  Serial.println (b);
  Serial.println (phi);
  Serial.print ("fonction cos "); Serial.println(abs (100*cos (2*PI*b/100)));
  Serial.print ("fonction lag "); Serial.println(abs (100*cos (2*PI*b/100- phi)));

What is the Firmata controller supposed to do with this crap?

By installing Firmata, you rendered the Arduino brain-dead. You then use Processing to tell the Arduino what to do. It is up to the Processing app to read the analog pin and use the value to however it sees fit.

Get rid of ALL the code you added to the Firmata sketch, and use the Firmata library in Processing AS INTENDED.
The art of getting good answers lies in asking good questions.

bvking

Sorry. We don't need firmata.

To send PWM from Arduino

Use   Serial.print (data);

a separator (here the coma). Serial.print(",");

if you have an array

use   Serial.println();

Code: [Select]

void loop() {
 
 
  if(flagTimer3) {
    asservissementMoteurs();     
    flagTimer3 = 0;

    // Affichage utile uniquement pour debugage
    for(uint8_t i = 0; i < NBMOTEURS; i++) {
      Serial.print(vitesse[i]);
      Serial.print(",");   
    }
    Serial.println();
  }
 
}


And in Processing use the fonction serialEvent

Code: [Select]

// import the Processing serial library
import processing.serial.*;   
Serial myPort; // The serial port
 
// Test values
int v0 = 0;
int v1 = 0;
int v2 = 0;
int v3 = 0;
int v4 = 0;

int x;
 
void setup() {
 
  size(640,480);
  // Open serial port
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[4], 115200);
 
  // Read bytes into a buffer until you get a linefeed (ASCII 10):
  myPort.bufferUntil('\n');
 
  //draw with smooth edges:
  //smooth();
  background(255);
}
 
void draw() {
 

 
  // Draw circles
  fill(25);
  ellipse(x, -v0, 5, 5);
  fill(50);
  ellipse(x, -v1+50, 5, 5);
    fill(75);
  ellipse(x, -v2+100, 5, 5);
  fill(100);
  ellipse(x, -v3+150, 5, 5);
  fill (125);
  ellipse(x, -v4+200, 5, 5);
 
  // Update x position
  x++;
 
  // Refresh screen
  if (x > width) {
    background(255);
    x = 0;
  }
}
 
// serialEvent  method is run automatically by the Processing applet
// whenever the buffer reaches the byte value set in the bufferUntil()
// method in the setup():
void serialEvent(Serial myPort) {
 
  // read the serial buffer:
  String myString = myPort.readStringUntil('\n');
 
  // if you got any bytes other than the linefeed:
  myString = trim(myString);
  //println(myString);
 
  // split the string at the commas
  // and convert the sections into integers:
  int values[] = int(split(myString, ','));
 
  if (values.length > 0) {
   
    v0 = values[0];
    v1 = values[1];
    v2 = values[2];
   
   
    println (v0);
    println (v1);
    println (v2);
   
   
   
   
  }
}

Go Up