0

Im trying to study a code that has

 array[0] = digitalRead(pin1);
 array[1] = digitalRead(pin2);
 array[2] = digitalRead(pin3);
 array[3] = digitalRead(pin3);
 array[4] = digitalRead(pin4);
 array[5] = digitalRead(pin5);
 array[6] = digitalRead(pin6);
 array[7] = digitalRead(pin7);

 for(i=0; i<8 ; i++){
  data[i] = array[i] + '0';
 }
 
 input = atoi(data);
 

im curious why did they add a '0'? when i try to run the code without the '0' it returns 0 which i assume is saying it can't be converted

rioV8
  • 24,506
  • 3
  • 32
  • 49
yellowsub
  • 3
  • 2
  • 2
    `atoi` takes a string of digits, not an array of numerical values. The digit `'0'` and the numerical value `0` are different. That `+'0'` takes care about that difference. – Gerhardh Oct 07 '22 at 08:36
  • Do you want to clean up the question's code before asking? The array index 'b' comes out of nowhere, and `atoi` will be looking for a null terminated string, not a series of ASCII digits followed by whatever... – Fe2O3 Oct 07 '22 at 08:40
  • can you please tell me how does a '0' make the array of numerical value into a string of digits – yellowsub Oct 07 '22 at 08:41
  • the b was a mistype sorry – yellowsub Oct 07 '22 at 08:42
  • typical bad arduino code – 0___________ Oct 07 '22 at 09:13
  • Assume it's a typo that pin3 is read twice? – Paul Lynch Oct 07 '22 at 09:33
  • 1
    Please post the declaration of every variable. It's highly relevant. Because if `data` is 8 bytes and not null terminated anywhere, `atoi` will crash & burn. – Lundin Oct 07 '22 at 09:44

2 Answers2

2

Short answer: '0' is added to convert interger values to ascii character values.

Explanation:

It's important to know that integer values like 0, 1, 2, ... are not the same as characters like '0', '1', '2', ... Characters do have an integer value that are defined in ascii-tables, see https://en.wikipedia.org/wiki/ASCII, but that value differs from the integer value. For instance the character '0' has the integer value 48. So to convert between an integer value (less than 10) and the corresponding character. There need to be some "conversion" - see later.

For your code:

digitalRead(pin1) returns an integer value being either 0 or 1

The purpose of the for loop is to generate a string that represents the value of the 8 pins. For instance like "10010110".

And finally the atoi call is to convert the string to an integer value. For instance converting the string "10010110" to the integer value 10010110 (decimal).

In order to construct the string from integer values that are 0 or 1, you need to calculate the integer value that represents the characters '0' and '1'. If you look-up ascii values, e.g. https://en.wikipedia.org/wiki/ASCII#Printable_characters , you can see that the character '0' has the decimal integer value 48 and the character '1' has the decimal integer value 49. So to go from integer value 0 to character '0' you need to add 48. Likewise - to go from integer value 1 to character '1' you need to add 48. So the code could be:

data[i] = array[i] + 48;

However, in C a character is considered an integer value. So instead of writing 48, C allows you to simply write the character that has the ascii-value 48. In other words:

data[i] = array[i] + 48;

is the same as

data[i] = array[i] + '0';

The compiler will automatically convert + '0' to + 48.

BTW: Make sure that data is defined as (at least) a 9 character array and that data[8] is already zero. Like char data[9] = {0};

That said... if array and data isn't used in other places, it seems a strange and complex way to calculate input. An alternative could be:

 input = 0;
 input = 10 * input + digitalRead(pin1);
 input = 10 * input + digitalRead(pin2);
 input = 10 * input + digitalRead(pin3);
 input = 10 * input + digitalRead(pin3); // pin3 twice in OPs code. typo??
 input = 10 * input + digitalRead(pin4);
 input = 10 * input + digitalRead(pin5);
 input = 10 * input + digitalRead(pin6);
 input = 10 * input + digitalRead(pin7);

and if the pins could be placed in an array the above could be placed in a simple and short for-loop

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
  • "The purpose of the for loop is to generate a string" Rather, the purpose of the loop is to generate an array of ASCII characters. A string would have to be null terminated, this code doesn't do that. (And it might not be necessary since the fixed size 8 is known.) – Lundin Oct 07 '22 at 09:36
  • @Lundin Exactly. However, OP didn't post the definition of `data` so we can't know for sure whether `data[8]` is already a string termination. So I wrote a "BTW" to mention exactly that. However as `data`is used as input to `atoi` I think it's safe to say the purpose is to "generate a string". Likewise we can't know for sure what `digitalRead(pin1)` returns but educated guessing is that it return 0 or 1. – Support Ukraine Oct 07 '22 at 09:51
-2

The code shown is silly. Why are (presumed) values of 0-1 being stored to a not-null-terminated array (NOT a string) then passed to a function to do this? :

unsigned char input = 0;
input = (input << 1) + digitalRead(pin1);
input = (input << 1) + digitalRead(pin2);
input = (input << 1) + digitalRead(pin3); // << THIS IS ORIGINAL OP CODE
input = (input << 1) + digitalRead(pin3); // << THIS IS ORIGINAL OP CODE
input = (input << 1) + digitalRead(pin4);
input = (input << 1) + digitalRead(pin5);
input = (input << 1) + digitalRead(pin6);
input = (input << 1) + digitalRead(pin7);

/* input's value now 0 to 11111111 (0-255) as an integer value. */
/* User assumes responsibility for LSB <=> MSB ordering of pins */
Fe2O3
  • 6,077
  • 2
  • 4
  • 20
  • Surely you mean `*= 10; input +=`. Your criticism is entirely valid, but wasn't worked into an answer to the question. If you had explained that the code is (unnecessarily) converting integer values (presumably in the range `0..9`) to decimal characters (in the range `'0'..'9'`, with emphasis on the quotes), and then worked in why that approach is silly (it uses unnecessary intermediate variables) then this might be an acceptable answer... – autistic Oct 07 '22 at 09:30
  • Err, the shift version you edited in is equally erroneous. – autistic Oct 07 '22 at 09:30
  • 1
    @autistic It's sometimes called a brain-fart.. Fixed to deal with a binary value from the function (that I didn't see documented, and didn't research...)... – Fe2O3 Oct 07 '22 at 09:34
  • This is **not** what OPs code is doing. It could be what it **should do** but this is completely different from OPs code – Support Ukraine Oct 07 '22 at 09:56
  • @SupportUkraine The OP's code is reading pin3 twice and passing an array of who-knows-what to a standard library function as if it really is a string. There's no indication if the target device can handle 32bit integers, and there's no indication that a sign bit is/has been considered... You've answered with your interpretation, and I've answered with mine... In a perfect world, NO ONE would answer until the Q&A for clarification in the comments was completed... It's not a perfect world – Fe2O3 Oct 07 '22 at 10:04
  • @SupportUkraine I see you've added a comment about the duplication of Pin3... Funny how some answers seem to improve when there are other answers to 'borrow' from... Funny, too, that a question like this: https://stackoverflow.com/questions/73983342/bizzare-bug-in-date-conversion-program receives absolutely no commentary about the problems, yet a "blinkered" answer is accepted and UV'd to death... Surreal place here in SO... – Fe2O3 Oct 07 '22 at 10:07
  • pin3 typo aside, OP’s code (and Answer #1) is reading “pins” that represent base 10 (pin7 = 10^0, pin6 = 10^1, etc.). Answer #2 is reading an 8-bit value. Apples and oranges, since OP’s intent is unclear. – Paul Lynch Oct 07 '22 at 10:34
  • "I see you've added a comment about the duplication of Pin3" yes I did. I noticed it from a comment by Paul Lynch that was made before you wrote it in your answer. – Support Ukraine Oct 07 '22 at 10:58
  • @PaulLynch ..."since OP’s intent is unclear." Yes. And, (pin 3 problem aside), integer values for a variable ranging from 0 to 11,111,111, with large tracts of "illegal" values makes absolutely no sense except, perhaps, as a CS50 credit card "_number_" type of question. Why multiply by 10, convert to ASCII, then convert to some improbable integer value? Makes no sense in the real world... – Fe2O3 Oct 07 '22 at 10:59
  • A lot of code on SO makes no sense in the real world, coming from homework or just people messing around. While the use of the names “pin#” and “digitalRead()” imply bit-level operations, OP’s code can build any 8-digit number, assuming digitalRead() returns 0-9 and data[] is somehow null-terminated. As @SupportUkraine pointed out, your code does something completely different, which understandable given OP’s choice of names. yellowsub, I hope at least you got your question answered. – Paul Lynch Oct 07 '22 at 11:43
  • 1
    @PaulLynch "And my friends/are all aboard/many more of them/live next door..." `:-)` https://www.arduino.cc/reference/en/language/functions/digital-io/digitalread/ Highs and Lows... That's what this life is all about... That, and a whole SO load of Blue Meanies!! – Fe2O3 Oct 07 '22 at 11:45
  • 1
    @Fe2O3 Thank you for that, I was not familiar with Arduino programming. – Paul Lynch Oct 07 '22 at 11:59
  • 1
    @Fe2O3 I visit here between the visits I get in real life, on the bank of life rn, so I understand. Speaking of waste, there once was a saying to sharpen our axe before we try to cut, and this attempt at this exercise is clearly not doing that. It'd be a shame to get help debugging an assessment only to fail because we didn't even consider reading the manual in full, which is part of the point of class exercises, to get us exploring/researching. By reading the manual I found out that Arduino chips don't use IO pins as OP expects; we get 2 per port, and ports likely have different baudrates. – autistic Oct 07 '22 at 20:56
  • 1
    There's also [this](https://www.arduino.cc/reference/en/language/functions/communication/serial/readbytes/), proving that there are people seem to only come here nowadays to ask us to do their research and debugging. SO caring only about whether an answer exists on SO is not good for the internet. – autistic Oct 07 '22 at 21:00
  • @autistic Thank you for gentle words in a maelstrom. Appreciate your comment very much! "Sharpen one's axe" VG!! Will start to use that expression, if I may... Re: "baudrates"??? I didn't see anything about "serial comms" in this... Re: "... not good for the internet" It's not good for software in general. Look what happened with "Heartbleed"... Not good 'nuff to just download, plug-in (and trust), and get the app out the door. No dollars for QC, it seems... One day the house of built of straw will blow away and some piggies will be caught and eaten... – Fe2O3 Oct 07 '22 at 23:33
  • 1
    I stand corrected. I'm not sure where I read that each pair of pins was intended to be ... well, it turns out they all default to input. – autistic Oct 08 '22 at 03:50