Few questions from a beginner

Hello,

I just started working on my first Arduino (and MCU) project, and I'm delighted how easy and fun it is to use it. I started building an L/C/F meter, and there are a few things I'm not sure about, since I never used MCUs before.

First, the hardware part: is THIS a good way to choose between 4 pins? Does floating pin counts as HIGH or LOW? Or is THIS configuration better? And, a digital pin that is pulled to ground for too long cannot damage the device, right?

Next, the software part: is there a nice, reliable piece of code used for resetting the device? If I remember correctly, pulling down the reset pin by controlling a transistor by the same chip is not recommended, right?

Any help/advice would be great, thanks in advance :slight_smile:

Miloš

is THIS a good way to choose between 4 pins?

No. (see next answer)

Does floating pin counts as HIGH or LOW?

Yes.

Or is THIS configuration better?

Much better.
Better still is to use the free built-in pullups.

And, a digital pin that is pulled to ground for too long cannot damage the device, right?

Right.

is there a nice, reliable piece of code used for resetting the device? I

Use the built-in watchdog

Pins that are not connected float. So there could be any value on them. For that reason the second option is better and you could use the button example is better except that you could leave out the resistor and turn on the internal pullup resistor with pinmode(mypin, INPUT_PULLUP);

I can't help with your other query.

So, I don't have to use the resistors at all? There's a pull-up resistor inside the MCU?

I will be transferring this circuit to PCB once the breadboard prototype is complete, so if those inbuilt resistors are a part of the board and not MCU, that's not useful to me.

And thanks for the answers guys :slight_smile:

They are in the MCU.

Thank you chillitronix :slight_smile:

ps: chillies rule

No problem.

Note that the internal resistors are pullups only, pullups being the recommended approach which makes your input active low. Your logic kind of upside down from what might be intuitive... low is "on".

If there's a compelling reason to use pulldowns- and there probably isn't- then you would need external resistors.

So, to sum things up, if I want to turn ON a pin, all I have to is define it with "pinMode(pin, INPUT_PULLUP)" and bring it down to the ground with a switch? Of course, I do understand the "low is on" thingie, that would be sorted inside the code.

And one more question, unrelated to any of the above, to avoid making a new thread, if I want to write a few functions outside the code ("void reset" that would reset the MCU and "int freq (pin)" that would return the frequency of the signal brought to the pin), where in the code do I define them? I mean, above the "void setup", below the "void loop", or between them?

I think you can define functions anywhere but for readability I would put them after the loop.

Anywhere but inside another function

Garurumon:
So, to sum things up, if I want to turn ON a pin, all I have to is define it with "pinMode(pin, INPUT_PULLUP)" and bring it down to the ground with a switch? Of course, I do understand the "low is on" thingie, that would be sorted inside the code.

Yep, look for a LOW with a digitalRead. (We probably ought to stop using the word "on", since that's not really appropriate when referring to the pin; it's either high or low.)

OK, got it, thanks guys :slight_smile: Gonna go and try to make it work now...

Btw, can I get my arduino bricked if I forget a bracket or something like that? Could a wrong code break it?

And I can't rewrite the MCU forever, right?

And thanks for the suggestion JimboZA, still getting used to everything here :slight_smile:

Can you brick it if you miss a bracket?

No, the code will not compile.

Can you brick it by getting it to do something that hogs the serial so bad that you can't re program it? Possibly... But I suspect it could be rescued.

That is awesome :slight_smile:

And about that watchdog, could anyone point me where can I find out how to use it for resetting arduino via code?

I suspect the WDT will be totally inappropriate for what you want to use it for. A better approach would be to reset all the necessary variables and then continue to run without attempting to reset the actual chip.

Well, here's an incomplete code with a reset I googled out, I dunno would that work. And why would it be inappropriate? Is often resetting harmful or something?

/* L/C/F/HF meter by Milos G. */

#include <LiquidCrystal.h> // includes LCD library
#include <avr/wdt.h> // including watchdog library for reseting the device

// chosing pins used for LCD screen, according to the wanted board layout:
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);
// choosing pins for selecting mode via rotary encoder
const int CONF1 = A0;
const int CONF2 = A1;
const int CONF3 = A2;
// global variable for the state of the rotary encoder
int state = 0;
// controlling the reed relay during the L/C meter calibration
const int REED = 3;
// signal inputs
const int LCIN = 2;
const int FIN = 1;
const int HFIN = 0;

//unused pins
const int UU1 = 4, UU2 = 5, UU3 = 6, UU4 = 7, UU5 = A3, UU6 = A4, UU7 = A5;

void setup() {
  // set LCD's dimensions:
  lcd.begin(16, 2);
  
  // setting up pin modes
  pinMode(CONF1, INPUT_PULLUP); // if LOW -> we measure L
  pinMode(CONF2, INPUT_PULLUP); // if LOW -> we measure C
  pinMode(CONF3, INPUT_PULLUP); // if LOW -> we measure F, in other cases we measure HF
  pinMode(REED, OUTPUT); // controlles the reed relay
  pinMode(LCIN, INPUT);
  pinMode(FIN, INPUT);
  pinMode(HFIN, INPUT);
  
  // terminating unused pins:
  pinMode(UU1, INPUT_PULLUP);
  pinMode(UU2, INPUT_PULLUP);
  pinMode(UU3, INPUT_PULLUP);
  pinMode(UU4, INPUT_PULLUP);
  pinMode(UU5, INPUT_PULLUP);
  pinMode(UU6, INPUT_PULLUP);
  pinMode(UU7, INPUT_PULLUP);
  
  // setup according to the position of the rotary switch
  if(digitalRead(CONF1) == LOW)
  {
    // L meter calibration
      
    // writing the title
    lcd.setCursor(0, 0);
    lcd.print("L:");
    state = 1;
  }
  else if(digitalRead(CONF2) == LOW)
  {
    // C meter calibration
      
    //writing the title
    lcd.setCursor(0, 0);
    lcd.print("C:");
    state = 2;
  }
  else if(digitalRead(CONF3) == LOW)
  {
    // writing the title
    lcd.setCursor(0, 0);
    lcd.print("F:");
    state = 3;
  }
  else
  {
    // writing the title
    lcd.setCursor(0, 0);
    lcd.print("F:");
    state = 4;
  }
}

void loop() {
  // all values are determined according to the frequency
  float freq = 0;
  // We have 4 situations
  switch (state) {
    case 1:
    {
      // if the rotary switch is turned, we need to reset the whole thing
      if (digitalRead(CONF1) != LOW)
      {
        // calls the reset funciton to reset the MCU since the rotary switch was turned
        reset();
      }
      
      float L = 0;
      // calls upon the frequency counting function
      freq = frequency(state);
      // calculating the Lx
      
      // writing the Lx on the screen
      lcd.setCursor(0, 1);
      lcd.print(L);
      lcd.print("H");
      break;
    }
    case 2:
    {
      if (digitalRead(CONF2) != LOW)
      {
        reset();
      }
      
      float C = 0;
      freq = frequency(state);
      // calculating the Cx
      
      lcd.setCursor(0, 1);
      lcd.print(C);
      lcd.print("uF");
      break;
    }
    case 3:
    {
      if (digitalRead(CONF3) != LOW)
      {
        reset();
      }
      
      freq = frequency(state);
      
      lcd.setCursor(0, 1);
      lcd.print(freq);
      lcd.print("Hz");
      break;
    }
    case 4:
    {
      if (digitalRead(CONF1) == HIGH || digitalRead(CONF2) == HIGH || digitalRead(CONF3) == HIGH)
      {
        reset();
      }
      
      // the signal is fed through /256 frequency divider
      freq = frequency(state)/1000000*256;
      lcd.setCursor(0, 1);
      lcd.print(freq);
      lcd.print("MHz");
    }
  }
}

// function that resets the MCU when called
void reset() {
  wdt_enable(WDTO_15MS);
  while(1)
  {
  }
}

// function that counts the frequency
float frequency(int x) {
  
  // local variable for storing frequency
  float freq = 0;
  // local variable for storing current pin
  int pin = 0;
  
  /*if (state == 1)
  {
    //pin = 
  }
  else if (state == 2)
  {
    
  }
  else if (state == 3)
  {
    
  }
  else
  {
    
  }*/
  
  return freq;
}

Why do you feel you have to get the Arduino to reset itself?

AWOL:
Why do you feel you have to get the Arduino to reset itself?

Well, you can look at the code above, how I imagined it. It has 4 different configurations, 4 ways to process the input signal, and I thought this would be a good way to go.

I don't think that would be a good way to go, but hey, that's just me.

const int CONF1 = A0;
....
  if(CONF1 == LOW)

Ask yourself, is 14 (assuming this isn't a Mega) ever going to equal LOW (aka zero)?
Did you miss a digitalRead?