Go Down

Topic: why analogRead return from 0 -1023 and analog write 0-255? (Read 7210 times) previous topic - next topic

necronet

I am a beginner in the arduino started kit but I've been playing around with map function and it seems that th analogRead can get values raging from 0- 1023 but whenever I want to do an analogWrite this should be from 0 - 255 why aren't both of them the same range?

larryd

The hardware timer is 8 bit (0-255) for the analogWrite on the UNO

Google is your friend:

https://www.arduino.cc/en/Reference/AnalogWrite   


.
No technical PMs.
If you are asked a question, please respond with an answer.
If you are asked for more information, please supply it.
If you need clarification, ask for help.

AWOL

Because the analogue to digital converter (analogRead) is a ten bit device, and the PWM timer (analogWrite) is eight bit.

larryd

If needed, you can use the TimerOne library to get a PWM on 9 and 10 to get a 0-1023 range.
Example:
Code: [Select]

#include <TimerOne.h>

void setup()
{
   pinMode(9, OUTPUT);
   pinMode(10, OUTPUT);
   Timer1.initialize(1000); //set period 1000us
   Timer1.pwm(9, 512);    //0-1023 is valid
   Timer1.pwm(10, 255); }

void loop()
{
 }
No technical PMs.
If you are asked a question, please respond with an answer.
If you are asked for more information, please supply it.
If you need clarification, ask for help.

dier02

Because the analogue to digital converter (analogRead) is a ten bit device, and the PWM timer (analogWrite) is eight bit.... so when I convert 10 bit to binary I get 1023 (whats?) - saying I convert 10 bits or 1023 bits to eight bits or 255 bits it gets a bit confusing.  Could someone please clarify this for me?

Wawa

With the decimal system you're used to you can write the number 255 with three digits.
Only three digits are needed, because each digit itself can have ten different 'levels (0-9).

A computer only works with yes/no, on/off, 1/0, so only two levels per digit.
It therefore needs more digits to write "255", actually eight (11111111).
There are ten digits needed to write "1023".

Lots of information about the binary number system online.
You need to understand that to fully understand the difference between 8-bit and 10-bit.

The analogRead part of basic Arduinos has a 10-bit resolution,
representing 0-1023 decimal (1024 steps/levels of accuracy).
So with the 5volt power supply basic Arduino processor are running on,
we can measure a voltage difference of 5volt/1024steps = ~5millivolt per step/level.

The digitalWrite part of the processor is 8-bit, so it only has 256 steps (0-255) e.g. for PWM output.
Enough resolution for most things, like controlling LED brightness or motor speed.

So if we control a motor with a pot connected to the analogue input,
we must convert 0-1023 coming from analogRead to 0-255 for PWM, or 10-bit binary to 8-bit binary.
That can simply be done by dividing by four. Or, more advanced, chopping off two bits with "bitshift".

The map function can also be used for that, but it's more suited to change the range, e.g. 0-1023 to 0-100 or to 50-255.
Leo..

GolamMostafa

#6
Oct 01, 2018, 02:55 pm Last Edit: Oct 01, 2018, 07:36 pm by GolamMostafa
I am a beginner in the arduino started kit but I've been playing around with map function and it seems that th analogRead can get values raging from 0- 1023 but whenever I want to do an analogWrite this should be from 0 - 255 why aren't both of them the same range?
Here, we have three functions: ananlogRead(arg1);, map(arg1, arg2, arg3, arg4, arg5);, and analgWrite(ar1, arg2);; these three functions can be combined as follows to do a new thing - what is this new thing?
Code: [Select]
analogWrite(arg1, map(ananlogRead(arg1), 0, 1023, 0, 255));

1.  What does analogWrite(arg1, arg2); function do?

Figure-1: PWM signals generated by analogWrite() function

When analogWrite(3, 0x20); is executed, the PWM signal of shape A (Fig-1) is generated at DPin-3 of UNO. The ON-period of the signal is determined by arg2 whose range is limited to (0 - 255 (0x00 - 0xFF). In this case, the ON-period is: 1020/28*0x20 =  127.5 us. arg2 determines the minimum time (the resolution) by which the ON-period of the PWM signal can be augmented. The PWM signal of the context is being generated by the 8-bit TC0 (Timer/Counter-0). The resolution is 1020/28 3.98 us.  

If we execute analogWrite(9, 0x20);, the PWM signal of shape B (Fig-1) will be generated at DPin-3 with ON-period = 2040/28*0x20 = 255 us. The ON-period is determined by arg2 whose value is limited to 0 - 255 (0x00 - 0xFF). The PWM signal is being generated by 16-bit TC1 and the resolution of this PWM signal is 7.97 us.

2.  What does analogRead(arg1); function do?

Figure-2: ADC Module of ATmega328P Microcontroller

When we execute the instruction :analogRead(A0);, the instruction samples the input DC voltage connected at A0-pin; connects the signal to the internal 10-bit ADC via analog channel Ch0; converts the signal into digital form; makes the signal available to the user via ADCH and ADCL registers. When the input DC voltage is 0V, the ADC value is 000000 00 0000 0000 (0); when the input DC voltage is 5V, the ADC value is 00000 11 11111111 (1023). By rotating the wiper of the pot R1 of Fig-2, we can vary the input DC signal from 0V to 5V; as a result, the ADC value will vary from 0x0000 - 0x03FF (0 - 1023). The value of ADCH and ADCL registers can be stored in the variable x by executing the instruction: unsigned int x = analogRead(A0);.

3.  What does the map(arg1, arg2, arg3, arg4, arg5); function do?
Assume that we want to observe that the ON-period of the PWM signal A of Fig-1 changes as the DC input to A0-pin (Fig-2) changes. To do it, the value of x of Step-2 must be entered as arg2 in this instruction: analogWrite(arg1, arg2); ---> analogWrite(3, x); ----> analogWrite(3, analogRead(A0));. But, we cannot enter the value of x directly into this function as x has the range 0 - 1023; whereas, analogWrite(arg1, arg2) function demands that its arg2 must have the range 0 - 255. Therefore, we need a function that will transform the range 0 - 1023 into 0 - 255. The map(arg1, arg2, arg3, arg4, arg5); function does this transformation. For example, the function transforms the value of arg1 (say, 978) into value 243 when we execute this instruction: byte y = map(978, 0 1023, 0, 255);. The variable y holds the values 243.

4.  The final codes to change ON-period of PWM signal A of Fig-1 as the wiper of R1 of Fig-1 moves from min value (0V) to max value (5V). The affect can be viewed by connecting a 220R+LED circuit at DPin-3.
Code: [Select]
unsigned x = analogRead(A0);
byte y = map(x, 0, 1023, 0 255);
analogWrite(3, y);

OR

ananlogWrite(3, map(analogRead(A0), 0, 1023, 0 , 255));

    

Serwan

Because the analogue to digital converter (analogRead) is a ten bit device, and the PWM timer (analogWrite) is eight bit.... so when I convert 10 bit to binary I get 1023 (whats?) - saying I convert 10 bits or 1023 bits to eight bits or 255 bits it gets a bit confusing.  Could someone please clarify this for me?
when you have 8 bit

the maximum number you can represent is 1111 1111 which is equivalent to 255


when you have 10 bit

the maximum number you can represent is 11 1111 1111 which is equivalent to 1023


Wawa

@ GolamMostafa

or

ananlogWrite (3, (analogRead(A0) >>  2));

Leo..


3dprinter

analogRead can get values raging from 0- 1023 but ... an analogWrite this should be from 0 - 255
 why aren't both of them the same range?
Others have explained the 8, 10 bit reason, but that does not answer why are not both of them 8bit?

Why settle for 8bit when you could have 10 or even 16 bits for both - 65thousand(plus) different steps. Or 32bit or ... but for a cheap microcontroller the cost / benefit stops at 10 bit for the analog input (requires more delicate electronics to resolve more bits), and likewise the timer dividers were choosen with the various clock frequencies in mind (more bits would need highr frequencies - more expensive chip)

Go Up