No data from Arduino using Serial object

R_Gol's icon

Hi,
I made a simple code in arduino to read value from analog pin using the Serial.print command.

I use the serial object in max to read those value but no data is coming through.

Any idea what it might be?
I am facing issue with my usb connections so I suspect it might be the issue?

Max Patch
Copy patch and select New From Clipboard in Max.


edit: Here is my arduino patch:

The value from the sensorPin are indeed print but no coming to max patch

int sensorPin = A0;    // select the input pin for the potentiometer
int sensorValue = 0;  // variable to store the value coming from the sensor

void setup() {
  Serial.begin(115200);
  
}

void loop() {
  // read the value from the sensor:
  sensorValue = analogRead(sensorPin);
  Serial.println(sensorValue);   
  // stop the program for for <sensorValue> milliseconds:
  delay(sensorValue);                  
}
Source Audio's icon

remove that delay(sensorValue);
and set to
delay(10); or more

in max set baud rate to what is set in arduino code.
then something should be received if you
select matching port.
use this to start with:


R_Gol's icon

Still nothing.
Arduino serial print is indeed printing data:

port is the same and also baud rate.

Source Audio's icon

1 serial port - 1 app at the time.
close arduino serial monitor

R_Gol's icon

I close arduino serial monitor and still nothing. Could it be issue with my USB ports?

Source Audio's icon

did you select proper port ?
look in max console after clicking on print
make message with port a
if your arduino is a, etc.

R_Gol's icon

Ok I found the problem. I used 115200 for the baud rate and that value is not available in max(?). I changed to 9600 and is just fine! Thanks.

I have a question regarding my patch below:

I try to make a system that doing the following:

System is receiving input from arduino. numbers between 0 to 1023.
When crossing below threshold (300) an audio file should start and play as long we stay below that value. When above that threshold the audio file should pause. When crossing below that value again the audio file will resume playing.

If crossing below that threshold and stay there for more then x time (lets say 5 sec in that example) - the audio file will continue to play until it end regardless if we cross that threshold again. the system will ignore any further input until finish the audio file.

How can I do the above?
what do you think on my patch? been in the max domain is fine or better to try and make everything at audio rate?

how can I create a small envelope of few milliseconds to prevent pops when pausing end resuming the audio file?

Thanks!

Max Patch
Copy patch and select New From Clipboard in Max.

R_Gol's icon

Here is an updated patch:

Max Patch
Copy patch and select New From Clipboard in Max.

working with play~ seems better option.
Still - can't figure out how to make this: If crossing below the threshold and stay there for more then x time (lets say 5 sec in that example) - the audio file will continue to play until it end regardless if we cross that threshold again. the system will ignore any further input until finish the audio file.

Source Audio's icon

Can't post any patches at this moment.

insert change after > 300 (threshold check)
use sel 1 0
you should reset onebang 1 after 5000 ms
to fade, use fadeout - del 20 - pause
resume - fade in

R_Gol's icon

Thanks for your help!
another issue I'm facing is with a simple line~ envelop

Max Patch
Copy patch and select New From Clipboard in Max.

you can clearly hear the fade when the envelope goes from 1 to 0 but no fade on the way from 0 to 1 .
What am I missing?

Source Audio's icon

nothing wrong.
both fades work

R_Gol's icon

Thanks

Source Audio's icon

You should simplify the whole thing.
As first send 0 or 1 from arduino, instead of full scale
analog readout.
This sends only if value changed
int Play = 0; int EXPlay = 0;
void setup() {Serial.begin(9600); }
void loop() {int IN = analogRead(A0);
if (IN < 300) {Play = 1;}
else Play = 0;
if (Play == 1 and Play != EXPlay)
{Serial.println(1); EXPlay = Play;}
if (Play == 0 and Play != EXPlay)
{Serial.println(0); EXPlay = Play;}
delay(10);
}

In Max all you need now is to react on 1 or 0.
here patch using matrix~ to fade.
100ms fade time and 5000 ms stable time

Max Patch
Copy patch and select New From Clipboard in Max.

If you want to keep arduino sending full analog readout, adapt
that in max.


R_Gol's icon

thanks for your help. the issue I might face with arduino sending only 1 or 0 with a constant threshold is that I will not be able to adjust the threshold based on different hands.
If sending full analog to max I can adjust the threshold within max based on the input.

such as this:

Max Patch
Copy patch and select New From Clipboard in Max.

Source Audio's icon

you can send threshold value to arduino via serial object.

R_Gol's icon

Any reson to send back and forth data between arduino and max? isn't easier/better sending full analog to Max and make the threshold filtering within maxm

edit: Do I need to add an external power supply to the arduino or I can Just power it via the USB port?

Source Audio's icon

Do it whatever way you prefer.
Why do you want to use external power supply ?
USB is enough to power up arduino

R_Gol's icon

Thanks for your help!
I've seen there is an option in the play~ object to specify more then 2 channels. I can also do 4 channels. How can I export 4 mono channels into one audio file with 4 different channels? or it is something for mc.play~?

Source Audio's icon

export 4 channels from where ?

R_Gol's icon

If I would like to add another stereo file to speakers 3&4 that will play only after a certain time how can I make it isync with the system that pause and resuming the play~ object for speakers 1&2?

so I thought that the easiest way whould be to have an audio file with 4 channels and then to wire output 3 & 4 from play~ object to DAC 3&4. like that I'm sure all audio are in sync.

miller john's icon

As first send 0 or 1 from arduino, instead of full scale analog readout. This sends only if value changed int Play = 0; int EXPlay = 0; void setup() {Serial.begin(9600); } void loop() {int IN = analogRead(A0); if (IN < 300) {Play = 1;} else Play = 0; if (Play == 1 and Play != EXPlay) {Serial.println(1); EXPlay = Play;} if (Play == 0 and Play != EXPlay) {Serial.println(0); EXPlay = Play;} delay(10); }
insert change after > 300 (threshold check) use sel 1 0 you should reset onebang 1 after 5000 ms to fade, use fadeout - del 20 - pause resume - fade in

R_Gol's icon

Thanks @MILLER JOHN .
The issue I'm facing with sending only 0 and 1 from arduino and therefore having a constant threshold is that the threshold I need to set is vary very much depends on human hands moisture, dry air and so on. This is why I need to build an adaptive system that change the threshold accordingly . Therefore sending only 0 or 1 from arduino with a constant threshold is not working as expected. In some cases even when a 1 is expected 0 is output due to a miss in the threshold number.

edit: apart of the above - what's wrong with sending full analog from arduino?

R_Gol's icon

ok - it seems that doing the filtering in arduino - sending only 0 or 1 to decide if to play or not the input data is much stable. when doing the filtering inside max it seems to be less stable. Is it something known that sending full analog to max is less stable then sending only 1 or 0 ?

What is those fade out and fade in ? can't find it in max

Source Audio's icon

I posted solution to have stable 1 or 0 output from serial object,
when arduino sends full scale.
Why don't you use it ?
If you prefer to send 1 or 0 from Arduino, I could post you the code
which would allow to set threshold from max to arduino,
just let me know what you decide.
----
You are asking a lot of questions, but they are not precise enough, at least not for me.
You want another stereo file to play into outputs 3 & 4 after some time,
let's say you start player 1 , it has time output, which one could use
to monitor curent play position.
You set player 2 to start playing when player 1 reaches 3000 ms.
All ok, but what happens when you pause player 1 at 5000ms ?
should player 2 continue or not ?
And what when player one comes to the end,
what should player 2 do ?
What if it is still playing, and you restart player 1 ?
And are both audio files of same length ?
and so on, too many unclear points.
If you describe exactly the playback relation of that 2 players,
it would be easy to make it.
---
then there is no fade in fade out object in max.
You use any available object that can control audio level to perform fading,
like that matrix~ in my patch, gain~ , *~ and so on.

R_Gol's icon

I posted solution to have stable 1 or 0 output from serial object,
when arduino sends full scale.
Why don't you use it ?
If you prefer to send 1 or 0 from Arduino, I could post you the code
which would allow to set threshold from max to arduino,
just let me know what you decide.

Yes, Thanks for your solution, I think it is working good with the data from arduino and I will use it.
Right now when crossing the 5 sec threshold the audio continue to play but it stops if another a zero is send again. I would like it to whenever crossing the 5 sec threshold the file will play until the end and to ignore any further input from the arduino. only when the audio file will reach its end a new input could be pause and resume the audio file.

You are asking a lot of questions, but they are not precise enough, at least not for me.
You want another stereo file to play into outputs 3 & 4 after some time,
let's say you start player 1 , it has time output, which one could use
to monitor curent play position.

You are right. I will try to explain my self better:
it should be another player that will have another stereo audio file at the same length of the audio file at player 1. lets call that player 2 which will be routed to output 3 & 4.

both player 1 and 2 should be in complete sync.
The audio file that is routed to output 3 and 4 should start when the audio file at player 1 is crossing the 5 sec threshold. So in order to be in sync with the audio file at player 1 the player 2 should pause and resume the same as player 1 but to be heard only when crossing the 5 sec threshold. when both audio files finishing (that should be at the same time) both are going back to their beginning.

I will try again explaining the whole project again as clear as I can:

Input data from arduino detecting close and open circuit between two persons.
when a contact has been made between the two person the Value 1 is output. when no contact is made - The value 0 is output. lets call it InValue.

two players inside max. Player 1 and Player 2. Both have a stereo files with the exact same length. Player 1 is routed to DAC 1 & 2 and player 2 is routed to DAC3 & 4.

when inValue = 1 player 1 will play. When inValue = 0 player 1 will pause. player 2 will follow those pause and resume message but will no output any signal to DAC 3 & 4 yet.

when inValue = 1 and remain 1 above 5 seconds (our THRESHOLD) player 1 will continue to play until it ends and ignoring any further inValues. So if the inValue is equal again 0 after crossing our threshold it won't pause our player.

The moment we cross our threshold so player1 will continue to play until it end player 2 will also play until it end, this time it will output signal to DAC 3 & 4. ( player 2 should have it's own envelope to allow longer fade in time)

when both player are done (they should be done at the same time) any new inValue will effect the system again (pausing and resuming the audio).

Source Audio's icon

Thank you, that is much better to understand.
That way both players ( or 1 player with 4 channels)
will allways play in sync, but channels 3 & 4
will fade in only if input was stable for 5 seconds.
That is easy to do.

Max Patch
Copy patch and select New From Clipboard in Max.


R_Gol's icon

This is great, thanks.
I try that the line~ envelope of player 2 will also control the fade out with no success.

Max Patch
Copy patch and select New From Clipboard in Max.


what is the 1 integer at player 1

R_Gol's icon

another issue I'm facing. when the audio play is finished and a new run should start (sending 0 and 1 to pause and resume the audio) player 2 line~ is stays at 1 before the threshold (5 sec) is reached.

Source Audio's icon

Audio player 2 is audible only if stable time is active, it will not pause or resume,
it can only stop when played to the end, same as player 1.
So I set fadeout to zero for it. We need muted state when playback starts.
Only fade in makes sense.
And you should not click on that, it is intended to work
on it's own when stable time status changes.
---
sfplay~ 2 nn 1 adds elapsed playback time outlet.
I used it for testing, but left single 1 by mistake in there,
that's why it does not bang when stop.
Simple remove it an use plain
sfplay~ 2
sorry for that mistake.
------
Your trying to make line fadeout :
How can you expect from a single message to accept both
set 1 $1 and set 0 $1 inputs at same time?
and then what should trigger the fade ?

this should be used if you need both adjustable :

only that in this case fade out makes no sense.

R_Gol's icon

only that in this case fade out makes no sense.

In order to make sense I should calculate the audio file length then to start the fade out envelope at the time of the file length minus the fade out time.

edit: is there a way the splay~ will output is location within it length?

Source Audio's icon

You should simply create fade out in audio files if you need fade at end.

If you want to learn about play position outlet
have a look in help file of sfplay~
in tab "more features" it shows example for time display.
to get info about audio file length: sfinfo~

R_Gol's icon

great. thanks for your help!

Source Audio's icon

hope you are getting good progress with this.
one thing was left to do -
to set threshold from Max.
Do you need that ?
Another option would be to use a pot on another analog input
and to map 0-1023 into usable threshold range.

But that might be questionable, depending on
what you use to detect if 2 people hold hands or not.
If you use floating inputs, with no pullup
or pulldown, than all analog inputs might influence the readout.

Could you post few infos about that ?
Skin resistance can vary from few Kohms to several Mohms
and you double that for 2 persons.
I would pull input to 5v using 10Mohm
resistor, one person should touch ground,
the other analog input, and whan they hold
2 free hands, you will have voltage drop.

R_Gol's icon

Could you post few infos about that ?

Yes, of course! here is the circuit I'm using:

A0 is pull up to +5V via R1 and C1 is stabilise cap.

regarding the change of the resistance in human resistance - that is why I wanted to have the full analog inside max and then to change the threshold point according to that.

but it seems that my code in Arduino doing just fine to send a stable 0 or 1 when a contact been made.
here is my Arduino code:

int sensorPin = A0;
uint16_t play = 0;
uint16_t explay = 0;
uint16_t inValue = 0;
uint16_t preInValue = 0;
unsigned long pMillis = 0;
const uint16_t THRESHOLD = 300;
unsigned long interval = 200;

const uint8_t threshold = 8;

void setup()
{
Serial.begin(9600);
}

void loop()
{
sensor();
}


void sensor()
{
//read every x interval//
if(millis() - pMillis >= interval)
{
pMillis = millis();
inValue = analogRead(sensorPin);
// don't print repeatition of numbers//
if( abs( inValue - preInValue) > threshold)
{
preInValue = inValue;
if(inValue < THRESHOLD)
{
play = 1;
}
else play = 0;

if(play == 1 and play != explay)
{
Serial.println(1);
explay = play;
}
if (play == 0 and play != explay)
{
Serial.println(0);
explay = play;
}
}
}
}

to set threshold from Max.
Do you need that ?

It seems I'm getting stable zero or one from Arduino. But what do you have in mind in order to set different threshold according to the contact that been made ?

Source Audio's icon

you complicated that simple code I posted.
overcomplicated.
You don't need both thresholds.
The circuit you use should work fine.
one person touching A0 wire produces no change in reading
or really minimal one.
you go from worst case, when hands are dry and resistance high.
even if both persons make 10Mohm, voltage would still drop
to 1/2.
You need only voltage drop threshold, like in my patch
but set it higher, 600 or so.
If you want to adjust it,
wire pot to A1 and map 0 1023 to threshold range .
---------
If you want to send raw readings to max,
then it makes sense to use

if( abs( inValue - preInValue) > threshold)

to avoid too many repeated values.
but not that complication using milis etc.

then you can set threshold for voltage drop in max.



R_Gol's icon

Can you also explain that part of the patch? the message " 0 0 1, 1 1 1" trigger each time a 1 is send as long the threshold of 5000 ms is not crossed right? what 0 0 1 follow by 1 1 1 mean? is it: set in 1 to 0 and in 2 to 0 and gain set to 1? then immediately after set in 1 to 1 in 2 to 1 and gain to 1 as well?

I also made my own version that should act the same. Do you have any comments on my patch? it seems to work just fine as well as the one you shared. although it might look more complicated.

Max Patch
Copy patch and select New From Clipboard in Max.

Source Audio's icon

message 0 0 1 tells matrix to set level of audio in 0 to audio out 0 to 1
message 1 1 1 tells matrix to set level of audio in 1 to audio out 1 to 1
message clear wipes connections - mute or level 0
both respect set ramp time
0 0 1, 1 1 1 - comma separated executes message itered.

level goes up on start and resume, down on pause.

I can only comment that the patch is too complicated for my taste,
but that is only my personal preference -
to use only as much objects as absolutely necessary

Source Audio's icon

P.S.
why do you do this to serial port on endfile ?

please remove all that.

R_Gol's icon

message 0 0 1 tells matrix to set level of audio in 0 to audio out 0 to 1
message 1 1 1 tells matrix to set level of audio in 1 to audio out 1 to 1
message clear wipes connections - mute or level 0
both respect set ramp time
001, 1 1 1 - comma separated executes message itered.

Thanks for explaining.

I found that if the max patch is open and the usb is disconnected and then connecting again the data from arduino will not transferred until I either close and open the patch or open and close the serial port.

What do you think about adding that:

Max Patch
Copy patch and select New From Clipboard in Max.

every time the file is finished to play it will reset the serial port so if connection has been lost it will reset the serial once in a while.
Is there any other method you can think of for making sure data will transferred from arduino in any situation ? apart of course if power is down and the computer is off.

edit: even a better idea - is there any way max can detect if the arduino is plug in and plug out?
so whenever a connection detect it will send a bang to open and close the serial.

Roman Thilenius's icon


make yourself a little abstraction for that 0 0 1 matrix stuff, or it will keep annoying you.

Source Audio's icon

why should one disconnect usb while max is using serial port ?
If arduino looses connection, you may have more serious problem.
If this is for installation, don't let computer go to sleep,
or on windows allow system to do any power management with usb devices.

If you want to be sure it is working, send something from arduino every few seconds,
and if it does not regularly arrive you can make alert,
send email or whatever.
Just separate that message from 0 or 1,
use for example letter A.

and only message needed to reactivate serial port is
port xy message.
if your arduino is on port b, then port b

R_Gol's icon

one thing was left to do -
to set threshold from Max.
Do you need that ?

could you please show what you had in mind in order to set the threshold from Max?

R_Gol's icon

why should one disconnect usb while max is using serial port ?
If arduino looses connection, you may have more serious problem.
If this is for installation, don't let computer go to sleep,
or on windows allow system to do any power management with usb devices.

Yes, I guess you right. It is for Installation - Max will one on windows pc.

If you want to be sure it is working, send something from arduino every few seconds,
and if it does not regularly arrive you can make alert,
send email or whatever.

Can I send email via Max? that is interesting but perhaps for a different topic

and only message needed to reactivate serial port is
port xy message.
if your arduino is on port b, then port b

What message?

Source Audio's icon

What message ?
Can't you read ?


Set threshold from max :


int Play = 0; int EXPlay = 0; int THRESH = 300;
void setup() {Serial.begin(9600); }
void loop() {while (Serial.available() > 0){
int xxx = Serial.parseInt();if (xxx > 10){THRESH = xxx;}}
int IN = analogRead(A0);
if (IN < THRESH) {Play = 1;} if (IN >= THRESH) {Play = 0;}
if (Play == 1 and Play != EXPlay)
{Serial.println(1); EXPlay = Play;}
if (Play == 0 and Play != EXPlay)
{Serial.println(0); EXPlay = Play;}
delay(50);}

in max

R_Gol's icon

What message ?
Can't you read ?

Sorry, I did not understand the way you phrase it. No I understand the the only message I need in order to reactivate the serial is the message: 'port' following by the port letter.

Thanks for you arduino threshold from max code suggesting as well!

R_Gol's icon

btw - is there any other relative easy way to detect if two persons holding hands together rather then the voltage divider method using an arduino?
Maybe there is perhaps a particular camera you can detect two hands held together with?

Source Audio's icon

no idea.
But maybe because of covid, you would prefer 2 people
to stick their hands into something,
rather than to hold each other's hands .
Any kind of sensor like LDR to interrupt light or
something similar per hand would do.

R_Gol's icon

Hi, I have a question regarding the "clocker" object.
For the moment a message "1" will start the clocker and message "0" will stop it and bring it to the beginning (counting from 0 again at the next "1").
Is it possible that the message "0" will only pause the clocker without reset it?
Only when the audio file is finished the clocker will be rest back to 0.

Source Audio's icon

that would make no sense,
because restarting clocker is needed to measure elapsed 5000 ms.
and you are wrong - it is not 0 that resets the clocker but 1 which restarts it.

if you need time counter with pause. resume etc use metro and counter

R_Gol's icon

that would make no sense,
because restarting clocker is needed to measure elapsed 5000 ms.

right now the system do the following: When receiving 1 from arduino the audio is playing and the clocker is running. when 0 is receiving the music is pause and the clocker is returning back to 0. When receiving 1 again the music is continue from were it stops and the clocker start to run from 0 again. if the clocker is passed 5000ms then the music will play until it ends.
every time the clocker is reset to zero when new 0 from arduino is arriving.

The only think I would like to change is that instead of the clocker reseting to zero in every new 0 from arduino, it will paused and continue is counting on every new 1 from arduino.

here is an example of what I'm trying to achive:

1 is send from arduino - music is playing and the clocker is running starting from zero.
after 1500ms - 0 is send from arduino, the music is paused and the clocker is paused at 1500ms (instead of inisialized to zero as before).
1 is send from arduino and the music resuming playing from where it paused.
after 2000ms - 0 is send from arduino. the music is paused and the clocker is now should paused at 3500ms instead of returning to 0.
1 is send again from arduino - the music resuming to play.
after 3000ms - 0 is send from arduino - but because the clocker should be now at 6500ms - the 5000ms threshold time has elapsed and the music is continuing playing until the end.
when the audio file is finish the clocker should be back to 0 .
is the above possible with the clocker?


R_Gol's icon

ok. conter and metro works like a charm! thanks! the only down size is the resolution of the counter

Source Audio's icon

what resolution
you can use metro 100 - is enough , or?
and count till 50 - is same as 5000 ms

R_Gol's icon

True. I'm using metro 100 >> counter >> *100 so I have 100ms intervals.

The issue I encounter: the bang at the end of the file is making the metro resuming also when the audio file is finished and it suppose to stop and back to zero.

Max Patch
Copy patch and select New From Clipboard in Max.

edit:
I fixed it -

Max Patch
Copy patch and select New From Clipboard in Max.

R_Gol's icon

I wanted to try a different version of that patch.
The way the patch is set is that arduino is sending either 1 or 0 above and below a certain threshold to start and pause the audio.
The data I'm receiving through the analog pin at the arduino is 0 to 1023. Can I use those value to control the amplitude of the sound? so instead of filtering that data inside arduino and sending only 0 or 1 - I wonder how can I use the full analog 0 - 1023 numbers to try and make the control of the volume more dynamic.
Is it possible or the data receiving from arduino will be "all over the place" meaning not really useful for the above.
If I want to try the above - what objects I should look into?

another way to explain is creating kind of envelope follower from the way the two hands are touching each other.



R_Gol's icon

So I try to scale the full analog input using the "scale" object. I scale the value between 1023 0 to 0 1 and connect that to a multiplier object to control the amplitude. The result is bad.

Max Patch
Copy patch and select New From Clipboard in Max.

arduino:

int sensorPin = A0;    
uint16_t sensorValue = 0; 
uint16_t psensorValue = 0;
unsigned long pMillis = 0;
unsigned long interval = 100;

const uint8_t  threshold = 8;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  sensor();
}


void sensor()
{
  //read every x interval//
  if(millis() - pMillis >= interval)
  {
   pMillis = millis();
   sensorValue = analogRead(sensorPin);
   // don't print repeatition of numbers//
   if( abs( sensorValue - psensorValue) > threshold)
   {
    Serial.println(sensorValue);
    psensorValue = sensorValue;
   }
  }
}
Source Audio's icon

what is bad ?
Simply describe what is wrong
Beside your arduino and max mistakes - even if you fixed that,
idea to use Hand Resistance for audio level -
I would say not good idea.
Resistance coud vary much as we allready stated depending on skin etc,
so you are probably happy if even switching works reliably.
But even if you manage to use some input range for audio level,
you are in trouble if audio should continue to play after
hands were held for 5 seconds, but as soon as
hands get separated, audio would mute.

no logic in the concept.

R_Gol's icon

I don't manage to map the values from the arduino analog pin to control the amplitude of the audio files in natural way. The value I'm reading are changing based on different people touching hands. some time the lower value I'm reading is around 13, other times is around 100.

Source Audio's icon

I expanded my message in the meantime,
please read it again

R_Gol's icon

I expanded my message in the meantime,
please read it again

True. After few tries I understand that switching properly is good enough for that type of work. Controlling amplitude with hand resistance of different people is indeed not a good idea.