Connecting and Unpacking or Routing from Arduino uno
Sorry just wasn’t sure if the images uploaded properly. Doing it from my iPhone so not used to how it looks
Connecting and Unpacking or Routing from Arduino uno
* Hi everyone
I have searched around, I found any solutions that match my problem or are up-to-date unfortunately.
I’m having trouble unpacking and/Or routing the data coming in from sensors attached to my Arduino uno. The senses are working fine when I check the Arduino serial monitor before I began looking at the PD patch.
I just can’t seem to get them to unpack, or route in PD 0.5
Just wondering if anyone else has solved this - or has found this to be a problem?
Attached are images of two separate Arduino Scripps I’ve tried. One to try unpacking, the other to try routing - Plus, an image of my pure data patch to try testing the incoming signal data.
![Arduino-Sensors Input-Unpack.png](/uploads/files/1729806028184-arduino-sensors-input-unpack.png) [sAp-Sensors Input Test.pd](/uploads/files/1729806028183-sap-sensors-input-test.pd) ![sAp-Sensors test-pd Image.png](/uploads/files/1729806028184-sap-sensors-test-pd-image.png) ![Arduino-Sensors Input-Route.png](/uploads/files/1729806028179-arduino-sensors-input-route.png)
Pi GPIO-pin serial communication with [comport]
Hi,
this is possible, I've been fiddling around with code and patch in this direction for some weeks now, starting with a Teensy LC and heavily leaning on excellent @alexandros Drymonitis tutorial "Arduino for Pd'ers". Sadly I damaged the Teensy (floating power supply wires - stupid me), and had to keep going using an Arduino Micro as a mere substitute (and a 5V-3V3 converter in between them), but I do remember that it was already working with the Teensy, sending values sampled from a potentiometer tied to A0 pin to a pd patch running on the Rpi.
As of now I am able to transmit in both directions, with various packet lengths depending of the type of data and as many "fluxes" as needed. My code and patch is by no means clean nor properly commented and I plan to share it in the future through GitHub. I could share this in a private way anyway, I just need a free evening to gather the bits and write some explanation lines.
In the meanwhile here are some tech points that come to my mind: (sorry this is rather "trivial", but in my experience such "trivial" topics can be time-consuming, sometimes)
-
connect Rx from one board to Tx of the other and GND together
-
use Serial1 (or higher indexes) for UART communication, Serial for common console debugging, as advised by the manufacturer PJRC
-
on linux I usually execute the command
sudo systemctl stop ModemManager
in a terminal first thing, if I remember well I had to find this workaround because the card couldn't be detected in Arduino IDE. (more of an Arduino Micro specific issue I guess but who knows...) -
sending data from the Teensy to the Rpi is easier (codewise) because you only have to create "packets" (i.e.: use start and end marker bytes to "frame" the relevant data) and send all at once. In the other way round (RPi->Teensy) you have to poll incoming data using a code structure that takes into account the fact that even with a high UART bitrate the Teensy will loop a great number of times, doing nothing, between incoming bytes because of its much higher clock frequency. See serial input basics - updated on arduino forums for more on that
Hope this will be useful, I'll try to pack up a decent recent version of my code and patch in order to share it soon.
Nau
Pd compiled for double-precision floats and Windows
@lacuna said:
Fixed point arithmetic can be exact...
You and I are on the same wavelength. Someone on the Arduino forum gave me a link to the Arduino printFloat() routine, so I rewrote it in Q4x60 fixed point (i.e. 4 bits of integer, 60 bits of fraction). It now prints out those excess digits correctly. So the issue with their library routine is that it uses doubles to calculate what to print for doubles, which just happens to print zeroes forever past the 10ths place in the case of 0.1 (but not other values, like 1.1). It's a simplistic algorithm due to resource constraints, i.e. why waste limited resources on correctly displaying digits beyond the precision limit? Someone else on the Arduino forum linked to a 15 page academic paper on how hard the fp print problem is--I'm only up to page 4
Pd compiled for double-precision floats and Windows
@jameslo said:
@ddw_music I love that story but am scratching my head over the 1/10 example you gave. Here's a test I made in Arduino c++: ... I went out 40 digits and didn't see anything unexpected. Was that example you gave just a metaphor for the issue, or is my test naive?
Not a metaphor at all:
[16, 17, 40].do { |prec|
"% digits: %\n".postf(
prec,
0.1.asStringPrec(prec)
)
};
16 digits: 0.1
17 digits: 0.10000000000000001
40 digits: 0.1000000000000000055511151231257827021182
As for Arduino, the float datatype reference says "Unlike other platforms, where you can get more precision by using a double (e.g. up to 15 digits), on the Arduino, double is the same size as float" -- so my guess here is that Serial places a limit on the number of digits it will try to render, and then fills the rest with zeros.
I went out 40 digits and didn't see anything unexpected.
Seeing zeros all the way out to 40 digits is unexpected! Arduino's output here is more comforting to end-users (which might be why they did that), but it isn't accurate.
Considering that Arduino calculates "double" using single precision, the output should deviate from the mathematically true value even earlier:
// 0.1.as32Bits = single precision but as an integer
// Float.from32Bits = double precision but based on the 32 bit float
Float.from32Bits(0.1.as32Bits).asStringPrec(40)
-> 0.100000001490116119384765625
The most reasonable conclusion I can draw is that Arduino is gussying up the output to reduce the number of "what the xxx is it printing" questions on their forum. That should not be taken as a standard against which other software libraries may be judged.
Edit: hmm, but here's Pd64.
Pd64 is doing it right, and Arduino is not.
Getting back to how Pd seems to differ from other programming languages, I'm going to hazard a guess and say that Pd hasn't separated the value of a float from its display/storage format.
The value must be stored in standard single/double precision format. You need the CPU to be able to take advantage of floating point instructions.
It's rather that Pd has to render the arguments as text, and this part isn't syncing up with the "double" compiler switch.
PS I hope my attempt at humor didn't discourage @porres from responding to @oid's question. I'm sure he would have something more meaningful to contribute.
Of patchers as programming languages... well, I got a lot of opinions about that. Another time. For now, just to say, classical algorithms are much harder to express in patchers because patchers are missing a few key features of programming languages.
hjh
Distance sensor in Bela Board
@lacuna said:
For me it is hard to know because information is missing:
This part I don't understand:and also to trigger this sample as soon as there is something echoing the trigger at a distance inferior of 15cm using a Threshold~ object
but this works already, doesn't it?
In which condition you want the sample to stop?
What kind of sensor?
What is attached to pins 11 and 12?
What data does [adc~ 12] output when moving hand?
Is [print Distance (cm) : ] about correct?
Which Bela tutorial are you referring to?[rzero~ 1] does some integration, I think. [dac~ 11] outputs ultrasonics? [line~] till 1000 and [adc~ 12] going into [samphold~] measures the time untill the reflected ultrasound is detected or sth like that?
Generally speaking, when developing something it is important to understand what is going on instead of blind copy&paste. And when asking, to provide all information you have to make it easy / possible to answer.
Hello, thanks for taking the time to answer my question, I really appreciate it; and sorry for having missed some important information.
This patch works as it will start playback when I put my hand on the sensor, but it won't stop playback when I remove my hand from the sensor range, and I'm still figuring out how to work this out. When I remove my hand the distance keeps going up, and thus the volume, until it reaches 25cm which is the limit I've put with [min25]. Your fade out patch makes sense but I still need something to bang it when I remove the hand from the sensor, putting a Threshold at 24cm for example kind of works, but it's not completely natural; imagine you're at 5cm and remove your hand, so the volume goes up to 24cm and then stops playback...
The sensor is the HC-SR04, pin 11 send triggers to ultrasonics every 60ms, echo receives feedback and sends it to pin 12, which with a time equation calculates distance. What [adc~ 12] outputs is a good question, I try to figure it out myself too, but it doesn't work with normal [print] command, not till it reaches [snapshot~] so then it outputs the distance in cm again. The distance is quite accurate, I think the real distance is a bit longer than the printed in console. The Bela tutorials are the official ones at https://learn.bela.io/tutorials/pure-data/sensors/distance-sensor/
What I've done at the moment is sample holding and snapshotting the distance so it stays in place, so if I want to "stop" the sample I just bring the distance near 0 with my hand very close bringing the volume near 0 and nearly unnoticeable, but the playback starts from the beginning with a [loadbang] is just that at any distance you'll put your hand the volume will go up. This works well in this case as the samples are standing notes, but it would be cooler if it starts from the beginning. I know there is some way to use this sensor as a trigger but I can't find any information.
Ultrasonic distance sensors with Pd in Bela
The ultrasonic distance sensors are usually digital, not analog. If this is the case, you're trying to read a digital signal as analog, which doesn't make much sense. This sensor has two pins, a trigger and an echo. You have to send a high voltage to the trigger pin, then pull it low, and read the echo pin which will help you compute the distance based on the time it took for this trigger pulse to arrive back at the echo pin.
The code below (copied from Arduino'g Project Hub), uses Arduino's pulseIn() function, to compute the distance:
// Define Trig and Echo pin:
#define trigPin 2
#define echoPin 3
// Define variables:
long duration;
int distance;
void setup() {
// Define inputs and outputs:
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
//Begin Serial communication at a baudrate of 9600:
Serial.begin(9600);
}
void loop() {
digitalWrite(trigPin, LOW);
delayMicroseconds(5);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Read the echoPin, pulseIn() returns the duration (length of the pulse) in microseconds:
duration = pulseIn(echoPin, HIGH);
// Calculate the distance:
distance= duration*0.034/2;
// Print the distance on the Serial Monitor
Serial.print("Distance = ");
Serial.print(distance);
Serial.println(" cm");
delay(1000);
}
I searched online and found the source of this pulseIn() function in Arduino's forum, which is this:
/*
wiring_pulse.c - pulseIn() function
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005-2006 David A. Mellis
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
$Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
*/
#include "wiring_private.h"
#include "pins_arduino.h"
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
* or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
* to 3 minutes in length, but must be called at least a few dozen microseconds
* before the start of the pulse. */
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
// cache the port and bit of the pin in order to speed up the
// pulse width measuring loop and achieve finer resolution. calling
// digitalRead() instead yields much coarser resolution.
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
uint8_t stateMask = (state ? bit : 0);
unsigned long width = 0; // keep initialization out of time critical area
// convert the timeout from microseconds to a number of times through
// the initial loop; it takes 16 clock cycles per iteration.
unsigned long numloops = 0;
unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;
// wait for any previous pulse to end
while ((*portInputRegister(port) & bit) == stateMask)
if (numloops++ == maxloops)
return 0;
// wait for the pulse to start
while ((*portInputRegister(port) & bit) != stateMask)
if (numloops++ == maxloops)
return 0;
// wait for the pulse to stop
while ((*portInputRegister(port) & bit) == stateMask) {
if (numloops++ == maxloops)
return 0;
width++;
}
// convert the reading to microseconds. The loop has been determined
// to be 20 clock cycles long and have about 16 clocks between the edge
// and the start of the loop. There will be some error introduced by
// the interrupt handlers.
return clockCyclesToMicroseconds(width * 21 + 16);
}
This is already getting complicated, as pulseIn() uses other functions which should be found and translated to Pd. I guess the best thing you can do is try to translate the first code chuck in this reply to Pd, and when you read a high voltage in the echo pin, do some math to calculate the distance.
In essence, set a digital input and a digital output pin on the Bela, trigger the output pin with a high and low signal, and keep reading the input pin (you should probably use a pull-down resistor there), until you get a high. Calculate the time it took with the [timer] object and do some simple math to get the distance. Do that with distances you know first, and then use the rule of three based on the known distance and the time you get. At least, that's how I would try to get this to work.
Another solution is to use an infrared proximity sensor, which is analog, and it's probably much easier to use. But this gets the proximity of obstacles right in front of it only, while the ultrasonic range finder has a wider field where it can detect obstacles.
Keyboard HID vs serial comport for Sensor values on pico
I'm trying to get values from analog sensors connected to a raspberry pi pico. That pico is plugged into a rp5 where I want to read those sensor values in Pure Data. Question-- to interface the pico's sensor values with the Pure Data I can either
Use the pico as a keyboard HID device (using MicroPython on the pico, and "HID" object in Pure Data), or
Use the "comport" object in pure data to unpack and read the sensor values over serial.
Does anyone have any thoughts about either way? Limitations or resolution(if that even applies). Someone please correct any of this- I'm thinking the HID might be a bit friendlier, both pi's and an audio interface are going in a Disney princess guitar I got from goodwill eventually, but I'm trying to get it functional first. I see values in pure data using a Logitech USB game controller and the "HID" object, and about 10 years ago I got sensor values over serial with the "comport" object in Pure Data with an Arduino Nano v3.1. I was reading a little about the u2if git repository that might be another option...and Just found out about the teensy boards... was thinking the teenzy 4.0 might be a better option. But- I haven't gotten this working, so that's first. I appreciate this space!
Arduino -> Pduino problem measuring lapsed time with [realtime]
Great input all of it, thanks!
@whale-av said:
@AndreasA You could probably round your data...... as you are always close to an integer (no 2 3 4 5 6 or 7).....
[expr int (0.5 + $f1) ]
.... maybe a [/ 10] first and a [* 10] after for the data we see....... but of course that is for a particular speed..... so maybe not?
You could also set a window large enough to accept changes as the speed varies, but filter numbers that are out of range (those around 20 in this case... or is it those around 10?) and reject them.
Yeah well didn’t give you enough information there. These numbers I get is at maximum speed of my wheel, or rather the lowest number that pd will output when over a certain speed. So I want it to be able to handle that and all slower speeds as well. The [smooth] is awesome, thanks for the tip!
@jameslo said:
@AndreasA I'm assuming that the numbers you are seeing in the Arduino IDE are timings you captured on the Arduino, not using [realtime], is that correct? If so I think @alexandros is suggesting that you send those timings to Pd, instead of trying to measure the times between Arduino messages on the Pd side.
Actually discovered some problems on the Arduino-side as well so I actually had both arduino and pd limit the output there for a while. But arduino is now definitely taken care of. With @alexandros method I’m closer to what I want but not quite there. Thinking about lowering the bar and deal with it as a limitation later on in the actual synth.
The thing with [realtime] was really interesting read. Good stuff to know!
Though, it would be awesome to have the resolution of serial_print but with firmata and pduino. Pduino is such a great interface for someone not use to coding and I’d like to add more sensors on the same arduino, which right now feels like a big undertaken without pduino and with my lack of knowledge.
Is there a way, do you think? Could I mess with the firmata code to add serial.print()? Obviously wrong forum, but just in case someone has tried.
Arduino -> Pduino problem measuring lapsed time with [realtime]
I’m trying to measure the speed of a wheel to control a synth. I’m using an arduino and Pduino. There is bits of papers taped to the wheel and they pass through a photo interrupter module. It’s using the digital output. I’m using the realtime-object to measure the time between papers passing the interrupter.
My question is why my output from [realtime] looks like this:
print: 9.917
print: 20.032
print: 19.994
print: 10.03
print: 10.025
print: 20.043
print: 18.553
print: 11.467
print: 20.026
print: 20.007
print: 9.879
print: 20.018
print: 8.59
print: 21.44
print: 10.032
print: 20.017
print: 20.02
print: 10.034
print: 18.484
print: 21.428
print: 10.032
And so on…
The numbers are always close to a multiple of 10. I can’t find a single integer ending with 2, 3, 4, 5, 6, or 7. Since I can se the numbers directly from the arduino (in arduino IDE) I’m pretty sure it’s not a problem at the arduino or sensor end of things. The numbers there looks totally reasonable to me. So, what is going on with my patch or with Pduino that makes it look like this? I could add that when using the timer-object there is nothing but exact multiples of 10:s outputted.
Also the stream of numbers I get is way to inconsistent for my uses and jumps around a lot. As you can see in the patch attached I’m using two [moving-ave] to smooth it out to something near acceptable. Is there limitations to using Pduino or is this again something in my patch.
Fairly new to PD and arduino so I’m sure there is a lot a can do better. Any help is appreciated. Thanks!
Patch:
PduinoTest.pd