pinMode(...) Required for digital output?

I’m working through the Starter Kit, Project 07 - Keyboard Instrument. Here’s my code but I’m wondering why it works with pinMode(…) commented out (Line 14 … line numbers not shown below).

BTW - I didn’t write my code exactly like the book but it’s essentially the same idea … I think.

//Pin values
const int keyPin = A0;
const int piezoPin = 8;

//Array of frequencies for each tone to be generated
int toneVals[4] = {262, 294, 330, 349};

//Global variables
int keyInputOld = 0;
int keyInputNew = 0;

void setup() {
  //Set pinmode for output to piezo
  //pinMode(piezoPin, OUTPUT);

  // Inititlaize Serial comms
  Serial.begin(9600);
}

void loop() {
  //Read new button press value, store old
  keyInputOld = keyInputNew;
  keyInputNew = analogRead(keyPin);

  //keyVal to indicate button pushed, initialized to an invalid value.
  int keyVal = -1;
  
  //Set keyVal (tone to generate) based input range from keyPin (0-1023)
  if(keyInputNew == 1023){
    //Button 1
    keyVal = 0;
  }else if(keyInputNew >= 990 && keyInputNew <=1010){
    //Button 2
    keyVal = 1;
  }else if(keyInputNew >= 505 && keyInputNew <= 515){
    //Button 3
    keyVal = 2;
  }else if(keyInputNew >= 5 && keyInputNew <= 10){
    //Button 4
    keyVal = 3;
  }

  //Serial output shows keyInput when it changes
  if(keyInputOld != keyInputNew){
    Serial.print("Key Input Old: ");
    Serial.println(keyInputOld);
    Serial.print("Key Input New: ");
    Serial.println(keyInputNew);
  }
  
  //Show tone on button press
  if(keyVal > -1){
    Serial.print("\t Key Value: ");
    Serial.print(keyVal);  
    Serial.print("\t Tone Value: ");
    Serial.println(toneVals[keyVal]);
  }
 
  //If keyVal is valid, generate tone.  Otherwise, no tone.
  if(keyVal > -1){
    tone(piezoPin, toneVals[keyVal]);
  }else{
    noTone(piezoPin);
  }
}

Many libraries setup the pinModes as does tone()

You can skip pinMode when you analogWrite, although using analogWrite(255) just to get rid of pinMode is a bit much

Thanks LarryD, I thought the tone function might be abstracting the pinMode(), but didn't see it documented.

Thanks INTP, I hadn't realized that an analogWrite() was happening. But I thought analogWrite() was reserved for PWN pins? My Piezo is on pin 8. Also, not sure what you meant by,

using analogWrite(255) just to get rid of pinMode is a bit much

UncleMoki: Thanks LarryD, I thought the tone function might be abstracting the pinMode(), but didn't see it documented.

Check the file C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\Tone.cpp; you will see the pinMode function being used there in the tone() function.

UncleMoki: Also, not sure what you meant by,

INTP: You can skip pinMode when you analogWrite, although using analogWrite(255) just to get rid of pinMode is a bit much

analogWrite(somePin,255) actually results in a digitalWrite(somePin, HIGH); see C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring_analog.c

Thanks sterretje - I see the pinMode() in Tone.cpp … I didn’t think to look at the code in the libraries so thanks for the heads-up.

Personally I would set the pinMode() in the main program even if it is also done in a library. That way it is obvious what is intended.

UKHeliBob - I’m the same when it comes to coding for software … but I’m new to coding with hardware and haven’t developed any intuition yet. Working with hardware feels like a higher stakes game. I admittedly battle mental images of one line of bad code turning my hardware into a little fireball, complete with sparks and mini explosions … like I’m flying a Tardis or something … which is a far cry from a YSOD I might get with a buggy web-app.

Example: I was just working with a project in the Starter Kit and the code uses a little for…loop to iterate through pins 2-7 and perform a digitalWrite() to LEDs. There’s also a sensor on pin 8. The looping code looks something like this:

...
for(int x=2;x<8;x++){
  digitalWrite(x, HIGH);
}
...

I started wondering - if I made a tiny mistake in the for…loop condition and accidentally included pin 8 in the digitalWrite() iteration …

...
for(int x=2;x<=8;x++){
  digitalWrite(x, HIGH);
}
...

… what would happen? Would the compiler see that pin 8’s pinMode is OUTPUT and error (my gut says no)? Would nothing happen? Would it damage pin 8 or the sensor connected to it? I want to find out but I don’t want to break my hardware when I only have the stuff that came with the starter kit. Plus I don’t like jump scares if my imaginations become reality :o .

DigitalWriteing a pin that is not output is totally valid - it turns the pullup on and off

But setting the pinMode for an input pin to output might indeed damage some hardware. In the simplest form you can blow a pin accidentally configured as output by pressing a button for a while. So there is indeed a risk that one can damage hardware.

DrAzzy: DigitalWriteing a pin that is not output is totally valid - it turns the pullup on and off

That is not portable, it happens to work on ATmega-based Arduinos, but you should use pinMode (?, INPUT_PULLUP) to enable pullups if you want your code to be general purpose and not limited to certain boards.

MarkT:
That is not portable, it happens to work on ATmega-based Arduinos, but you should
use pinMode (?, INPUT_PULLUP) to enable pullups if you want your code to be general
purpose and not limited to certain boards.

MarkT - Your comment about portability is appreciated, at least by this newbie. But it also got me on the rabbit trail of wondering how portable I should expect any of my Arduino code or the libraries underneath to be? I’m not being a wise-guy as your question sincerely got me thinking. My initial thought was that the code MIGHT be compiling to machine code since it is writing to the microcontroller. So like assembly, the compiled machine code should theoretically work on any microcontroller with matching architecture. But then there’s the board’s specs and it’s host of supporting components … and the libraries that might leverage the board specific characteristics. So after spending some time trying to find the answer myself via the web and thinking about the question, my guess is that much of what I’m writing is probably not very portable. Would you agree? Or am I wrong and maybe I COULD do something like grab a Parallax board and setup a driver so the Arduino IDE sees it and expect the “blink” example to work (assuming a Parallax board with an led on pin 13)? Again, not being a wise-guy, I’m sincerely wondering.

Thanks all … I’ve been rummaging through the documentation about the various libraries and there’s a lot to take in … but the deeper I dive, the more answers I’m finding (and questions I’m generating). Really glad I made the decision to explore the world of microcontrollers through the Arduino.

Arduino code is portable within the Arduino family; it basically stops after that.

I have no experience with a C/C++ for a PIC, but I'm quite sure that it does not know about a pinMode function.