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?
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);
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.
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?
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.)
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.
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;
}
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.