Avoid analogRead from getting random values.

So, as far as I know, the analogRead inputs (A0, etc) get volts if something is plugged in, but if it's not plugged it gets a random number.

Is this random number created by the arduino?, or it gets from the environment. If its a random value generated by the arduino, is there any way to disable that?

I want to create a antenna (EM receiver) with arduino. I know that to do that I need to metal rods (can be open wires?) and be connected to a receiver of electricity (rigth?). Then if it doesn't gets electricity I want to know too thats why I'm asking.

I mean I can show you the code but its so simple, for now:

const int PIN = A0;

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

void loop(){
  Serial.println(String((double)analogRead(PIN) * 5 / 1023));
}

I would like to know some information about how to do that if you know it too.

Thank you in advance!!

It’s from the environment. It really outputs the voltage at that moment. But the input impedance of an analog pin is very high so it will pick up almost everything.

And your project isn’t even close as simple as you suggest it… It will be not very simple…

And about your code, wow. So much crap in a single line!

  • Why make it a String?
  • Wtf is the cast to double doing there?
  • How sure are you about the 5V?
  • And the 1023 should be 1024 :wink:

septillion:
It's from the environment. It really outputs the voltage at that moment. But the input impedance of an analog pin is very high so it will pick up almost everything.

And your project isn't even close as simple as you suggest it... It will be not very simple...

And about your code, wow. So much crap in a single line!

  • Why make it a String?
  • Wtf is the cast to double doing there?
  • How sure are you about the 5V?
  • And the 1023 should be 1024 :wink:

I make it a String because I print it to the Serial.
Cast to double because the analogRead reads integrer and then usually (at least in c++ pure) when you divide an integrer it doesn't transform to float or double it mantains in integrer, I want the floated value.
Oh! And by the way yes it should be 1023 because it reads 10-bit = 2^10 = 1024 and is 0-1023 counting the zero ;). You can check it by plugging in the A0 to the 5v and it will appear 1023 (5v is the maximum).

I know that I could use better a float I just wrote it fast to test, and also maybe a double is better for more accuracy, but the fact is that it doesn't matter that much in velocity for the little code there.

GuillemVS:
I make it a String because I print it to the Serial.

Serial is perfectly capable of printing integers and floats

GuillemVS:
Cast to double because the analogRead reads integrer and then usually (at least in c++ pure) when you divide an integrer it doesn't transform to float or double it mantains in integrer, I want the floated value.

No you don't :wink: You want a decimal point. That's not the same!

But okay, it will give you a double as a result. But do note, on a lot of Arduino's a double is the same as a float. (And floats are slooooowwwww on most Arduino's.) You can also just multiply by a float aka by 5.0 :wink:

GuillemVS:
Oh! And by the way yes it should be 1023 because it reads 10-bit = 2^10 = 1024 and is 0-1023 counting the zero ;).

WRONG! :wink: You want to divide by the number of steps. If you want to divide something into buckets labeled "Bucket 1", "Bucket 2", "Bucket 3", "Bucket 4" and "Bucket 5", you divide by 5 don't you? So why would you divide by 4 if you label them "Bucket 0", "Bucket 1", "Bucket 2", "Bucket 3" and "Bucket 4"?

GuillemVS:
You can check it by plugging in the A0 to the 5v and it will appear 1023 (5v is the maximum).

But at that moment you're actually overflowing the ADC. It will already read 1023 from a voltage of 4,995V :wink:

septillion:
Serial is perfectly capable of printing integers and floats
No you don't :wink: You want a decimal point. That's not the same!

But okay, it will give you a double as a result. But do note, on a lot of Arduino's a double is the same as a float. (And floats are slooooowwwww on most Arduino's.) You can also just multiply by a float aka by 5.0 :wink:
WRONG! :wink: You want to divide by the number of steps. If you want to divide something into buckets labeled "Bucket 1", "Bucket 2", "Bucket 3", "Bucket 4" and "Bucket 5", you divide by 5 don't you? So why would you divide by 4 if you label them "Bucket 0", "Bucket 1", "Bucket 2", "Bucket 3" and "Bucket 4"?
But at that moment you're actually overflowing the ADC. It will already read 1023 from a voltage of 4,995V :wink:

Let's plug the A0 into the ground, it returns 0 (without any multiplication) then means that the maximum that will input is 1023, no? Because if it inputs 1024 from a 5v it means that it will have 1025 of space. And that is not how the bits work. If the maximum that will ever input is 1023 then why divide by 1024? It doesn't make sense to me.
Second of all I just entered google to search if you were right and I found that even the Arduino says that is between 1023 you can check it out https://www.arduino.cc/en/Tutorial/ReadAnalogVoltage

The thing about the 5.0 I didn't know about it good to know but it guess it makes the same.

And also I know that the println is able to print floated values, but it helps me to not get used to a high level programming to do things by myself that maybe the language will do anyway (I started with C# and I changed to c++, I didn't knew lots of things).

And the first purpose of my question wasn't to teach me how to code, but how to disable the randomness, and if it isn't possible (because it comes from the environment) how to do the project itself.

Sorry I left one thing: :wink:

At least can someone tell me how to do such thing?

What thing? Are you building a radio receiver? Then analogRead() will give random results because it cannot operate at radio frequency.

GuillemVS:
Let’s plug the A0 into the ground, it returns 0 (without any multiplication) then means that the maximum that will input is 1023, no?

Not that it’s a cause and effect, but yes, on a 10-bit ADC the max value is 1023. Which is outputted when you apply a voltage of 4,995V or above. (<= Key sentence)

GuillemVS:
Because if it inputs 1024 from a 5v it means that it will have 1025 of space.

If it could go to 1024, if would. But it can’t, so it’s clipped. Try inputting 5,3V (which is perfectly in spec if Vcc is 5,0V). That is also just clipped to 1023.

GuillemVS:
And that is not how the bits work. If the maximum that will ever input is 1023 then why divide by 1024?

Because that’s the amount of “buckets” you have. Numbered 0 to 1023.

GuillemVS:
It doesn’t make sense to me.

Then answer reply #3 (two questions):

septillion:
If you want to divide something into buckets labeled “Bucket 1”, “Bucket 2”, “Bucket 3”, “Bucket 4” and “Bucket 5”, you divide by 5, don’t you? So why would you divide by 4 if you label them “Bucket 0”, “Bucket 1”, “Bucket 2”, “Bucket 3” and “Bucket 4”?

GuillemVS:
Second of all I just entered google to search if you were right and I found that even the Arduino says that is between 1023 you can check it out https://www.arduino.cc/en/Tutorial/ReadAnalogVoltage

Ahh, the “it’s on the internet so it must be right!” card! Unfortunately this is one of the more persistent errors people make. Just like people wonder why they don’t have a resonsive Arduino when the code is full of delays. And we’re simply here to correct that :wink:

Let me quote from the datasheet (page 205 if you want to know):

The minimum value represents GND and the maximum value represents the voltage on the AREF pin minus 1 LSB.

GuillemVS:
The thing about the 5.0 I didn’t know about it good to know but it guess it makes the same.

But remember, a float (or double or any other type of floating point) isn’t simply a decimal point! Just saying :slight_smile:

GuillemVS:
And also I know that the println is able to print floated values, but it helps me to not get used to a high level programming to do things by myself that maybe the language will do anyway (I started with C# and I changed to c++, I didn’t knew lots of things).

You mean by using an even higher level (crappy) library? That doesn’t make ANY sense to me :wink:

And why have a grudge against higher level? That’s what makes writing code quick and portable. And is THE key point of using Arduino in the firs place!

GuillemVS:
And the first purpose of my question wasn’t to teach me how to code, but how to disable the randomness, […]
Sorry, but if I see BS, I will point it out so people can fix it / learn more down the way.

GuillemVS:
[…] and if it isn’t possible (because it comes from the environment) how to do the project itself.

Now that’s a whoooooole different story. Like I said, it’s from the environment and the ADC is right when outputting the random values. At that moment the voltage that is represented by the ADC is really present on the input of the ADC.

So I second what MorganS asks, what are you trying to do? My guess is that you are wayyyyyyyyy over your head.

You want to divide by the number of steps. If you want to divide something into buckets labeled "Bucket 1", "Bucket 2", "Bucket 3", "Bucket 4" and "Bucket 5", you divide by 5 don't you? So why would you divide by 4 if you label them "Bucket 0", "Bucket 1", "Bucket 2", "Bucket 3" and "Bucket 4"?

Thank you septillion, I have been looking for that answer for ages and now you point it out it's bleeding obvious and I should have worked it out for myself.

++Karma.

septillion:
Not that it’s a cause and effect, but yes, on a 10-bit ADC the max value is 1023. Which is outputted when you apply a voltage of 4,995V or above. (<= Key sentence)
If it could go to 1024, if would. But it can’t, so it’s clipped. Try inputting 5,3V (which is perfectly in spec if Vcc is 5,0V). That is also just clipped to 1023.
Because that’s the amount of “buckets” you have. Numbered 0 to 1023.
Then answer reply #3 (two questions):Ahh, the “it’s on the internet so it must be right!” card! Unfortunately this is one of the more persistent errors people make. Just like people wonder why they don’t have a resonsive Arduino when the code is full of delays. And we’re simply here to correct that :wink:

Let me quote from the datasheet (page 205 if you want to know):But remember, a float (or double or any other type of floating point) isn’t simply a decimal point! Just saying :slight_smile:
You mean by using an even higher level (crappy) library? That doesn’t make ANY sense to me :wink:

And why have a grudge against higher level? That’s what makes writing code quick and portable. And is THE key point of using Arduino in the firs place!
Now that’s a whoooooole different story. Like I said, it’s from the environment and the ADC is right when outputting the random values. At that moment the voltage that is represented by the ADC is really present on the input of the ADC.

So I second what MorganS asks, what are you trying to do? My guess is that you are wayyyyyyyyy over your head.

It’s not about the buckets, it’s about the value.
When you talk about buckets you are talking about the size of the array, yes there are 5 buckets, but you won’t get to five Buckts[4] is the maximum, then let’s say that you want to get a value from 1 to 0 about the arduino analogRead, if you divide between 1024 you won’t ever get to 1, and you would like that the maximum value is the 1, right? I understand what you are saying, about the buckets, but you don’t get the same output if you do it. If you divide 1 - 5 buckets between 5 you will get values from 0 (without counting 0) to 1. If you divide 0 - 4 buckets between 5 you will get values from 0 to 1 (without counting 1). Not the result we want, not even in the first place. What you want is values from 0 to 1 counting 0 and 1. In the first thing, from 1 - 5, to get values from 0 to 1 you would have to substract 1 / 5 and then divide between 4 / 5. Too much calculations for getting a 0 to 1 value.
For example:
You are working with three dimensional vectors in a 3d space, and you want to normalize the speed of an object, to get the direction. It’s speed is (5,4,3) (it moves that amount per second). To normalize it (0 to 1) you won’t use the size, because there is no size! You would use the maximum value (that is 5) the normalization would result in (5 / 5, 4 / 5, 3 / 5) or (1, 0.8, 0.6). That is the direction of the object, in (5,4,3) there is no 6 value or 7 or above 5, the maximum is 5. There is no size or nothing, but you just wanna have it from 0 to 1. I understand your theory, but (as I have shown you) in neither of the cases I get what I want that is a 0 to 1 value, that’s why we don’t use size to get this.
There are 1024 points, but 1023 steps.
As far as I know the arduino analogRead reads between 0v and 5v counting the 0v and 5v, then if the maximum value is 1023, what I just said is the correct way to do it.
If what you are telling me is that 5v would be 1024, because the arduino doesn’t reads that high, then what you say is true, but as far as I’ve seen isn’t what it says in everywhere (even in the arduino page).

What I said about the libraries (I see you like the word crap), so if you have been involved in coding beyond arduino, you would’ve noticed that there are levels of coding (high = less programming but also most of the times = less speed) C# is a high level programming language, actually you can add a bool to a string and itself will convert the bool to string and append it to the other string, so what I’m trying to say is: I got used to that, and I changed to c++ (not arduino, pure c++) and I didn’t know lots of things, the parsing was way different the to string was way different, actually string was not part of the program (like in C#), so what I like to do is to remind me what’s going on by doing operations that the same language would do. You would say it doesn’t help, I say it’s just my way of coding. Also another reason, is that maybe I wanted to add more things to the string, then if I had (for example) added a char to the value of float, maybe it would have added the char ascii value to the floated value or another weird thing. I’m just coding thinking about what could I add to make it simpler to change afterwards without losing speed. It’s just a way to do it. It’s not about libraries as you’ve said high level = low level + added functions to make it simpler and classes. That is actually what the c++ arduino has.

What you’ve said “it’s on the internet it must be correct”, first of all you just answered a bunch of things said nothing made me lose time and I don’t have what I asked for still (basically I questioned everything you’ve said). So just for that I don’t believe everything that puts on the internet. But let’s be clear: if you buy a TV of samsung and in the same page of samsung says something that you have to do with the tv before opening it. Are you going to do it or not? Because if you haven’t seen it, the link is from the arduino page. Who’s more reliable, the creators or one guy that appears that says something that is opposite to that. I don’t know man/woman. You are actually asking me to “believe everything that puts in the internet with that”. And let’s be clear, I have the result that I wanted 0 to 1 value (with the arduino way).

You say it’s clipped, but in almost every place it says that it can actually reach to 5v you can search (0 - 5v).

I just want to ask something that maybe would be really helpful (apart from the 5.0). To create a omnidirectional antenna, I just need to use a metal rod of a length (defined by the wave length) and then what? Read the values that the metal rod receives?
If that’s it, if I receive different volts values, means that is different wave lengths that fit in that one? If that’s true, what is the rate of sending information of the radio? I know that there is a fixed time to send bits (like 1 is the wave and 0 isn’t and there is a time in which you wait), does that apply to radio waves too (in the same way)?

GuillemVS:
[…] if you divide between 1024 you won’t ever get to 1, and you would like that the maximum value is the 1, right?

You might like that to happen, but that’s not what is happening :wink: See the quote from the datasheet. The largest value it can represent is, and I quote, “the voltage on the AREF pin minus 1 LSB”.

VAREF by default is Vcc aka (for the sake of simplicity) 5,000V. So in order to represent 5,000V you would need the max value (aka 1023) +1 (LSB) aka 1024. So each step is 5,000V / 1024 = 4,883mV big. The fact the ADC can’t represent 1024 but only to 1023 makes the largest value the ADC can represent 5,000V / 1024 x 1023 = 4,995. Aka, 1 step (aka 1 LSB) less than VAREF.

So you might like it to go to 5,000V, the device does not do that :slight_smile:

GuillemVS:
You are working with three dimensional vectors in a 3d space, and you want to normalize the speed of an object, to get the direction. It’s speed is (5,4,3) (it moves that amount per second). To normalize it (0 to 1) you won’t use the size, because there is no size!

How can you say there is no size?! It’s size is sqrt(52 + 42 + 32) = 7. So the normalized vector is (5/7; 4/7; 3/7) = (0,7; 0,6; 0,4).

As a rule, the length of the normalized vector is 1. Your vector (1; 0,8; 0,6) has length sqrt(12 + 0.82 + 0.62) = 1,4 so isn’t the normalized vector.

GuillemVS:
(I see you like the word crap),

I say what I think it is :slight_smile: And yeah, for stuff I don’t think is good I indeed like the word crap because it’s a pretty soft word. But as a Dutch, I don’t have a problem using stronger language but I like to keep it nice around here :smiley:

GuillemVS:
so if you have been involved in coding beyond arduino, you would’ve noticed that there are levels of coding (high = less programming but also most of the times = less speed)

I have, thank you :slight_smile:

GuillemVS:
so what I like to do is to remind me what’s going on by doing operations that the same language would do. You would say it doesn’t help, I say it’s just my way of coding.

Ahh, but that’s an entirely different reason! You liking it vs nonsense about higher level :wink: I don’t say it’s wrong, just saying you are wasting resources with it. And if you make a habit out of it, the memory fragmentation is likely to bite you one day.

GuillemVS:
Also another reason, is that maybe I wanted to add more things to the string, then if I had (for example) added a char to the value of float, maybe it would have added the char ascii value to the floated value or another weird thing. I’m just coding thinking about what could I add to make it simpler to change afterwards without losing speed.

But you don’t have a string :wink: You have a String. Which is not the same.

Also, it is again wasteful to try and make a string (or String) first if all you’re doing with it is sending it over a stream. You might think it looks ugly but

Serial.print("he");
Serial.print("llo");
Serial.print(" w");
Serial.print("orld");
//has exactly the same result as
char text[15] = "Hello";
strcat(text, " world");
Serial.print(text);
//but the later is using more resources

Aka, you might not lose speed when you add stuff but you already lost speed to start with.

GuillemVS:
But let’s be clear: if you buy a TV of samsung and in the same page of samsung says something that you have to do with the tv before opening it.

No, I will not just do it without thinking. I will think about it whether it makes sense. Never had a manual with an error in it?

And yeah, I notice the error in the tutorial page. Might be a good moment to push a correction to repository :slight_smile:

GuillemVS:
Who’s more reliable, the creators or one guy that appears that says something that is opposite to that.

In this case? The “one guy that appears that says something that is opposite to that” because he points to the source documents supporting his claim :slight_smile:

GuillemVS:
To create a omnidirectional antenna, I just need to use a metal rod of a length (defined by the wave length) and then what?

Build a RF front-end. Use a LP filter to remove anti aliasing. Do some (basic) calculations about the impedance matching. Be sure to control the sample rate and to conform to Nyquist. And use BP in software to get the signal. let me know on which part you’re stuck.

GuillemVS:
Read the values that the metal rod receives?
[…] what is the rate of sending information of the radio?

What is “the radio”? It’s 2019, everybody has at least 5 radio’s in their pocket. Even my washing machine has a radio in it. Are we talking about FM audio?

It’s not about the buckets, it’s about the value.

.Perhaps you’re unfamiliar with how the successive approximation converter works.

For the record, AVR say 1024.

Hint: do a simple reductio ad absurdum,.and imagine a one bit SA converter.
Do you divide the reading by one (21-1), or by two?

AWOL:
.Perhaps you’re unfamiliar with how the successive approximation converter works.

For the record, AVR say 1024.

Hint: do a simple reductio ad absurdum,.and imagine a one bit SA converter.
Do you divide the reading by one (21-1), or by two?

septillion:
You might like that to happen, but that’s not what is happening :wink: See the quote from the datasheet. The largest value it can represent is, and I quote, “the voltage on the AREF pin minus 1 LSB”.

VAREF by default is Vcc aka (for the sake of simplicity) 5,000V. So in order to represent 5,000V you would need the max value (aka 1023) +1 (LSB) aka 1024. So each step is 5,000V / 1024 = 4,883mV big. The fact the ADC can’t represent 1024 but only to 1023 makes the largest value the ADC can represent 5,000V / 1024 x 1023 = 4,995. Aka, 1 step (aka 1 LSB) less than VAREF.

So you might like it to go to 5,000V, the device does not do that :slight_smile:
How can you say there is no size?! It’s size is sqrt(52 + 42 + 32) = 7. So the normalized vector is (5/7; 4/7; 3/7) = (0,7; 0,6; 0,4).

As a rule, the length of the normalized vector is 1. Your vector (1; 0,8; 0,6) has length sqrt(12 + 0.82 + 0.62) = 1,4 so isn’t the normalized vector.
I say what I think it is :slight_smile: And yeah, for stuff I don’t think is good I indeed like the word crap because it’s a pretty soft word. But as a Dutch, I don’t have a problem using stronger language but I like to keep it nice around here :smiley:

I have, thank you :slight_smile:
Ahh, but that’s an entirely different reason! You liking it vs nonsense about higher level :wink: I don’t say it’s wrong, just saying you are wasting resources with it. And if you make a habit out of it, the memory fragmentation is likely to bite you one day.
But you don’t have a string :wink: You have a String. Which is not the same.

Also, it is again wasteful to try and make a string (or String) first if all you’re doing with it is sending it over a stream. You might think it looks ugly but

Serial.print("he");

Serial.print(“llo”);
Serial.print(" w");
Serial.print(“orld”);
//has exactly the same result as
char text[15] = “Hello”;
strcat(text, " world");
Serial.print(text);
//but the later is using more resources



Aka, you might not lose speed when you add stuff but you already lost speed to start with.
No, I will not just do it without thinking. I will think about it whether it makes sense. Never had a manual with an error in it?

And yeah, I notice the error in the tutorial page. Might be a good moment to push a correction to repository :)
In this case? The "one guy that appears that says something that is opposite to that" because he points to the source documents supporting his claim :)
Build a RF front-end. Use a LP filter to remove anti aliasing. Do some (basic) calculations about the impedance matching. Be sure to control the sample rate and to conform to Nyquist. And use BP in software to get the signal. let me know on which part you're stuck.
What is "the radio"? It's 2019, everybody has at least 5 radio's in their pocket. Even my washing machine has a radio in it. Are we talking about FM audio?

Thank you so much for the quick answers, but I hope you understand that if in the Arduino page says that thing and I’m getting visible results right now, I guess it’s because it works (maybe is clipped). If I ever have the time or opportunity to see if it doesn’t work, I let you know. For now, I’m good with that.
Sorry for the time lost in trying to change my mind. And also, the thing about the 3d I don’t really know why I said that (I wasn’t trying to say about normalizing, I don’t even know how that’s done), I just wrote fast trying to put like another answer to the thing.

Yes! I mean the FM audio (I’m not english, I don’t know if it wasn’t clear when I said radio, but here when we say radio it means that). And the thing about the AVR and that sutff (I don’t even know what you are talking about xD).

Given what I’ve read, I’m not sanguine about the success of this enterprise.

GuillemVS:
Thank you so much for the quick answers, but I hope you understand that if in the Arduino page says that thing and I'm getting visible results right now, I guess it's because it works (maybe is clipped).

You could divide by 1000, that would also get you close / visible results. Without really measuring you would probably not even notice either.

GuillemVS:
And the thing about the AVR and that sutff (I don't even know what you are talking about xD).

Clearly :wink: Arduino's are just dev boards to make connecting easy. On most the micro controller used is an AVR, on the facto standard Uno it's a ATmega328p for which I linked the datasheet.

But apparently you want to ignore that document. So here some reading if you ever have time:
Arduino analogRead() reference page
Post of great Nick Gammon
Another well explain (with images!) article

GuillemVS:
If I ever have the time or opportunity to see if it doesn't work, I let you know.

It's not that it doesn't work (the expression "it doesn't work" is by the way the most terrible explanation from an engineering perspective), it that it's incorrect.

GuillemVS:
Sorry for the time lost in trying to change my mind.

Yeah, it's a wider problem nowadays that you can't convince people of the truth even if you hand them the facts...

GuillemVS:
Yes! I mean the FM audio (I'm not english, I don't know if it wasn't clear when I said radio, but here when we say radio it means that).

Here, in normal life it could mean that but in day to day life that would also include DAB+ and (internet) streaming. But on a technical/engineering level (and that's what I assume on a technical forum) it could be anything from AM ((audio broadcast)) to Bluetooth to LoRa to 5G.

But the project you're suggest is not feasible. One reason being that an Arduino can't conform to Nyquist if it comes to audio broadcast FM.

BTW, here's a microcontroller-based Software Defined Radio project built by someone who knows what their doing:

Yeah, he does know what he's doing :slight_smile: Teensy is indeed way more suitable for the task. And nice use of undersampling :slight_smile: But the theory is strong on this one. If you can do that you're effectively (past) half way your degree in electrical engineering :smiley: