I'm new, and have a very basic understanding of coding. I have written the following code for an Attiny85 to run a PWM driver for hot wire cutting from a 3s lipo (12v) battery.
I have written the sketch to check the voltage of the battery and either produce a tone on a piezo OR run the code that checks if a button is pressed and then turns on the PWM output. That way, when the voltage drops too low on the Lipo, the PWM will not be able to run.
Do you see any flaws in the code functionally? Any advice on how I could have done it better?
int PWMPin = 0; //PWM output pin
int PIEZOPin = 1; //peizo output pin
int POTPin = A1; //POT input pin on P2
int VOLTPin = A2; //To measure voltage on P4
const int buttonPin = 3; // assigns pushbutton to pin 3
int buttonState = 0;
void setup() // setup loop
{
pinMode(buttonPin, INPUT_PULLUP); //sets buttonPin to input
pinMode(PWMPin, OUTPUT);
pinMode(POTPin, INPUT);
pinMode(VOLTPin, INPUT);
}
void loop() {
int Vbatt = analogRead(VOLTPin); // Read analog voltage on VOLTpin
if (Vbatt < 5)
{
tone(PIEZOPin, 10000, 50);
delay(100);
} else {
buttonState = digitalRead(buttonPin); // read the state of the pushbutton value
if (buttonState == LOW) {
int POT = analogRead(POTPin); // Read analog voltage on pin 2 (A1)
analogWrite(PWMPin, POT / 4); // Output analog reading to dimmable LED
} else {
digitalWrite(PWMPin, LOW);
}
}
}
I have not loaded/tried this code since adding the voltage check if/else section. I just wanted some more confidence before I wire it up with a battery and fry something! ;D
Thanks!
Without connecting PWMPin, add code to light up the onboard LED or add Serial.print statements to show what it is doing. Then see if it outputs what you're expecting, when you're expecting it.
It's called testing and debugging, which you should do yourself.
Pete
I have been testing and debugging it myself, the whole time, just not SINCE I added the voltage check if/else section...LIKE I HAD STATED.
I have not loaded/tried this code since adding the voltage check if/else section.
I was more interested in feedback about coding, timing issues, issues with using if/else, or something I may not know about or understand yet.
I know the code will work.
Thanks for the suggestion though.
Yes, I READ WHAT YOU WROTE and what you wrote meant that you had not tested the additional code. If you had been testing and debugging it "the whole time", why did you stop just because you had added an if statement? Are you going to come back asking for a "review/critique" each time you add a new statement to that code?
Temporarily change the definition of PWMPin to int PWMPin = LED_BUILTIN; //PWM output pin
When you push the button, adjusting the pot should alter the brightness of the LED.
If it doesn't, then you've got some thinking to do.
Pete
Yes, except on most Arduinos the built in LED is not capable of PWM. It will be off for values less than 127 and on solid for higher.
The first line in loop may be an issue. analogRead does not return a voltage from 0 - 5. It returns a ten bit number between 0 -1023 where 1023 represents 5V. I can't tell if you were looking for Vbatt to be less than 5V or less than 24mV which is what you have now.
I used the on board LED for testing at first, now I have an external LED driven by a mosfet, just for testing purposes, and it does behave that way.
Thank you, Delta_G.
I was looking for 5v and not 24mv.
Where did you get 24mv from? (even though it is irrelevant)
Should I use
void loop() {
int Vbatt = VOLTPin * (5.0 / 1023.0); //Read and convert VOLTPin
//int Vbatt = analogRead(VOLTPin); // This is the wrong code
if (Vbatt < 5)
{
tone(piezoPin, 10000, 50);
delay(100);
} else {
Thanks, again!
interestingfellow:
Where did you get 24mv from? (even though it is irrelevant)
5V full range divided by the 1023 steps possible times the 5 value you used.
int Vbatt = VOLTPin * (5.0 / 1023.0); //Read and convert VOLTPin
Yes, that's the way to get voltage, but be aware that you might not see exactly 1023 every time. Leave yourself a little wiggle room.
OK, *now I'm asking for troubleshooting help, and I'm almost sure it's hardware related and not code related.
I used several different batteries and a dmm to calibrate the voltage divider (4700k/2200k) and the code. My target low voltage is 10.3v which works out to 576/1023. I was going to covert to and use Volts in the sketch, but I felt like x/1023 would be more accurate.
I have it all on the bread board running off a 3s lipo (12.53v on Vin).
Once plugged in the piezo starts beeping indicating a low voltage situation.
The divider is set up to be read on P4. When the divider is hooked up and I check from P4 to Gnd I read 1.41v.
If disconnect the divider from P4 and check just the divider to ground I read 3.42v (as expected).
"Low" voltage is 2.817v.
I've looked over the breadboard/schematic and can't find a loop or short. Why is it the divider reading 1.41v when connected? What am I doing wrong?
int pwmPin = 0; //PWM output pin
int piezoPin = 1; //peizo output pin
int POTPin = A1; //POT input pin on P2
int VOLTPin = A2; //To measure voltage on P4
const int buttonPin = 3; // assigns pushbutton to pin 3
int buttonState = 0;
void setup() // setup loop
{
pinMode(buttonPin, INPUT_PULLUP); //sets buttonPin to input
pinMode(pwmPin, OUTPUT);
pinMode(POTPin, INPUT);
pinMode(VOLTPin, INPUT);
}
void loop() {
//int Vbatt = VOLTPin * (5.0 / 1023.0); //Reads VOLTPin to 5v as Vbatt
int Vbatt = analogRead(VOLTPin); // Read analog voltage on VOLTpin
//if (Vbatt < 2.82) // 2.82v sets cutoff for 10.3v
if (Vbatt < 575) // 575 out of 1023 sets cutoff for 10.3v
{
tone(piezoPin, 10000, 50);
delay(100);
} else {
buttonState = digitalRead(buttonPin); // read the state of the pushbutton value
if (buttonState == LOW) {
int POT = analogRead(POTPin); // Read analog voltage on pin 2 (A1)
analogWrite(pwmPin, POT / 4); // Output analog reading to dimmable LED
} else {
digitalWrite(pwmPin, LOW);
}
}
}
12.53 is too much on Vin. You might damage the board. The max is 12V but it's a good idea to stay well under that as the on-board voltage regulator can get quite hot at that voltage.
Do you think that's what was causing the wierd voltage reading on the devider/P4?
I thought the 7805 series was good to something like 30v?
interestingfellow:
I thought the 7805 series was good to something like 30v?
How much voltage you can feed them also depends on how big of a heat sink you have for them. The one on the Arduino has almost none.
Yes, heat sink. Do you have a recommendation? I already have ceramic thermal epoxy to glue it on.
But, also.... I currently have 12v going to the potentiometer instead of 5v, and *that might be screwing up my voltage divider!
I'll play around later and double check.
EDIT
I changed cleaned up the breadboard and fixed the pot voltage issue.
It still does not operate correctly.
Hi,
Try 4k7 and 2k2 resistors for your potential divider, you are using 4700k and 2200k, or 4M7 and 2M2, they are way too high.
Measure the volts at pin 4, and see if your divider is working properly.
Tom....
Hi,
I think this is what you need.
The gnd of the MOSFET source should also be as close as possible to the LiPo -ve terminal.
Tom...
THANK YOU!!!!!!!!!!!!!!! (to everyone, btw)
I had read that when measuring voltage you(pl) want to use higher resistor values so as to affect the circuit being measured as little as possible. What I didn't account for is the high resistance on the attiny85 pin?
I switched to 4k7 and 2k2 and it still didn't work *properly.
Taking readings on the voltage divider in circuit I discovered the value was dropping lower than when measured out of circuit, I'm assuming because of Attiny85 resistance effecting the divider. After making a new calculation and adjustments for the "low voltage" cut off it now works! I think.....because I haven't got a battery at the "low" voltage cut off yet.
Question: when measured out of circuit, I have calculated the safest Vss max of 15.9v with a 4k7/2k2 divider, and 29v with the 4k7/2k2 when in circuit. Does that sound possible? Safe?
I may use this with a laptop power supply for hot wire cutting, so 29v is high enough. Yes, I'm going to heatsink the vregulator (and also the mosfet) anyway.
Now i'm going to add some blinky lights to let me know if it is "on" or "firing", and then transfer it to some veriboard and a case!
-----THANK YOU, AGAIN, ALL OF YOU!-----
I know how obnoxious noobs are, and I do try my hardest to troubleshoot and research issues before posting to the forums. I'll post a vid back for giggles, after I get it boxed up.
Hi,
Question: when measured out of circuit, I have calculated the safest Vss max of 15.9v with a 4k7/2k2 divider, and 29v with the 4k7/2k2 when in circuit. Does that sound possible? Safe?
Can you show how you calculated this?
I agree with the out of circuit.
15.9 * 2.2/(4.7 + 2.2) = 5V
How does the voltage need to be that high when in circuit, the analog input of the Attiny is not that low is it?
With the divider in circuit can you measure the voltage across the total resistance, and the voltage across the 2k2 resistor.
Thanks.. Tom..
V - 2k2 V - Ratio V - 2k2 Vin circuit - Ratio
11.92 - 3.75 - 3.178666667 11.92 - 2.24 - 5.321428571
11.27 - 3.54 - 3.183615819 11.27 - 2.195 - 5.134396355
11.03 - 3.47 - 3.178674352 11.03 - 2.18 - 5.059633028
25v, not 29v. Sorry.
The set to the left represents voltages measured out of circuit, and to the right measured in circuit. I used 3 different batteries for measurements and averaged the values for calculations; 5v*Ratio=Vmax
5v on 2k2 out of circuit would be 15.9v
5v on 2k2 in circuit would be 5v*5.17=25.8v
thank you!