Arduino code help, way out of my depth - Overclock.net - An Overclocking Community

Forum Jump: 

Arduino code help, way out of my depth

 
Thread Tools
post #1 of 4 (permalink) Old 02-28-2018, 09:54 PM - Thread Starter
New to Overclock.net
 
5291Crash's Avatar
 
Join Date: Dec 2004
Location: Landsowne, Ontario, Canada
Posts: 563
Rep: 26 (Unique: 26)
Arduino code help, way out of my depth

Hey all

I am trying to make a simple controller on a Nano board, that watches A0, A1, and A2 for voltage reference from a voltage divider circuit, and puts the to the output

The idea being that the controller will look at the inputs in order A0-A2 and always give preference to the first one that meets criteria.

i am using 12vdc , setting cut off points at 11.8-14.5v

Inputs
A0 - Wall wart power
A1 - External Batt
A2 - Internal batt

Outputs are
D11 - LED and mosfet for power relay
D12 - LED and mosfet for power relay
D13 - LED and mosfet for power relay

This is where i hit a coding wall from pure lack of knowlege
In basic i need it to look at A0 and if its in range use it turning on d11, but if its not in range move to A1 doing the same. BUT it can only run one output at a time.


Kind of like this

if a0 <=11.8 but >=14.5 put d11 high, else d11 low

if d11 high skip to end else do next

if a1 <=11.8 but >=14.5 put d12 high, else d12 low

if d12 high skip to end, else do next

if a2 <=11.8 but >=14.5 put d13 high, else d13 low.

end

This is my current unfinished code i have modded from a single i/o setup that worked on my test bench.
Code:
/*
  DC Voltmeter
  An Arduino DVM based on voltage divider concept
  T.K.Hareendran
  This is reworked into a voltage controller monitoring 3 inputs to chose the right output.
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
const int a0 = 0; // Main PSU input voltage of 12.5 or better
const int a1 = 1; // External Battery input voltage range no lower than 11.8v flooded
const int a2 = 2; // Internal Battery input voltage range no lower then 11.8v sla
const int led_d11 = 11; // Controls LED and power mosfet for PSU
const int led_d12 = 12; // Controls LED and power mosfet for External Battery
const int led_d13 = 13; // Controls LED and power mosfet for Internal Battery
float vout0 = 0.0;
float vout1 = 0.0;
float vout2 = 0.0;
float vin0 = 0.0;
float vin1 = 0.0;
float vin2 = 0.0;
float R1_0 = 4610.0; // R1 input A0(4.7K) -Measure for exact!
float R2_0 = 2163.0; // R2 for input of A0(2.2K) - Measure for exact!
float R1_1 = 4700.0; // resistance of R1 for input of A1(4.7K) -Measure for exact!
float R2_1 = 2200.0; // resistance of R2 for input of A1(2.2K) - Measure for exact!
float R1_2 = 4700.0; // resistance of R1 for input of A2(4.7K) -Measure for exact!
float R2_2 = 2200.0; // resistance of R2 for input of A2(2.2K) - Measure for exact!
int value = 0;
void setup() {
  pinMode(a0, INPUT), (a1, INPUT), (a2, INPUT);
  pinMode(led_d11, OUTPUT), (led_d12, OUTPUT), (led_d13, OUTPUT);
  lcd.begin(20, 4);
  lcd.print("Batt Mon V1.0");
}
void loop() {
  // read the value at analog input
  vout0 = (value * 3.98) / 1023.0; // see text 4.5 being reference voltage
  vout1 = (value * 3.98) / 1023.0; // see text 4.5 being reference voltage
  vout2 = (value * 3.98) / 1023.0; // see text 4.5 being reference voltage
  value = analogRead(a0);
  vin0 = vout0 / (R2_0 / (R1_0 + R2_0));
  if (vin0 < 0.09) {
    vin0 = 0.0; //statement to quash undesired reading !
  }
  lcd.setCursor(0, 1);
  lcd.print("PSU V= ");
  lcd.print(vin0);
  lcd.setCursor(0, 2);
  lcd.print("EXT BATT V= ");
  lcd.print(vin0);
  lcd.setCursor(0, 3);
  lcd.print("INT BATT V= ");
  lcd.print(vin0);
  if (vin0 < 2.5) {  // <------------- This is where i am trying to sort out (number values are from initial test bed i have now built a 3 output 0-13.8v test bed)
    digitalWrite(led_d13, HIGH);
  } else {
    digitalWrite(led_d13, LOW);
  }
  if (vin0 > 3.0) {
    digitalWrite(led_d13, HIGH);
  } else {
    digitalWrite(led_d13, LOW);
  }
  delay(500);
}
screen output i will tinker with later, i may not use it.
reference voltage is from a 4.5v with ±0.04% tolerance.
I want to use this as i can mod the code to fit whatever voltages i need. unlike something bought.

I'm not asking for finished code, but to be pointed in the right direction on getting it done.

Thanks all,
Joe

Ryzen
(12 items)
CPU
Ryzen 5 2600X
Motherboard
MSI x470 Gaming Plus
GPU
MSI Armour RX 570 8GB OC
RAM
Team Group TDGED416G3000HC16CDC01 2x8GB 3000Mhz C16
Hard Drive
WD Black 500 GB NVMe
Power Supply
Rosewill Capstone 750
Cooling
Cheap 240 AIO
Case
Rosewill Rise
Operating System
Win 10 Pro
Keyboard
Microsoft Sidewinder x4
Mouse
Logitech G300s
Audio
Audio Technica M50xBT
▲ hide details ▲
5291Crash is offline  
Sponsored Links
Advertisement
 
post #2 of 4 (permalink) Old 03-01-2018, 02:13 AM - Thread Starter
New to Overclock.net
 
5291Crash's Avatar
 
Join Date: Dec 2004
Location: Landsowne, Ontario, Canada
Posts: 563
Rep: 26 (Unique: 26)
Where i am now
Code:
 if (vin0 < 0.09) {
    vin0 = 0.0; //statement to quash undesired reading !
  }
  lcd.setCursor(0, 1);
  lcd.print("PSU V= ");
  lcd.print(vin0);
  lcd.setCursor(0, 2);
  lcd.print("EXT BATT V= ");
  lcd.print(vin1);
  lcd.setCursor(0, 3);
  lcd.print("INT BATT V= ");
  lcd.print(vin2);
  if (vin0 < 14.4 && vin0 > 11.8) {
    digitalWrite(led_d11, HIGH);
  } 
  else {
    digitalWrite(led_d11, LOW);
  }
  if (led_d11 = LOW && vin1 < 11.8 && vin1 > 14.4) {
    digitalWrite(led_d12, HIGH);
  } 
  else {
    digitalWrite(led_d12, LOW);
  }
  if (led_d11 = LOW && led_d12 = LOW && vin2 < 11.8 && vin2 > 14.4) {
    digitalWrite(led_d13, HIGH);
  } 
  else {
    digitalWrite(led_d13, LOW);
  }
  delay(500);
fails at my attempt to look at the outputs

Edit:
up to this now
Code:
  if (vin0 < 0.09) {
    vin0 = 0.0; //statement to quash undesired reading !
  }
  lcd.setCursor(0, 1);
  lcd.print("PSU V= ");
  lcd.print(vin0);
  lcd.setCursor(0, 2);
  lcd.print("EXT BATT V= ");
  lcd.print(vin1);
  lcd.setCursor(0, 3);
  lcd.print("INT BATT V= ");
  lcd.print(vin2);
  if (vin0 < 14.4 && vin0 > 11.8) {
    digitalWrite(led_d11, HIGH);
  } 
  else {
    digitalWrite(led_d11, LOW);
  }
  if (vin0 > 14.4 && vin0 < 11.8 && vin1 < 11.8 && vin1 > 14.4) {
    digitalWrite(led_d12, HIGH);
  } 
  else {
    digitalWrite(led_d12, LOW);
  }
  if (vin0 > 14.4 && vin0 < 11.8 && vin1 > 14.4 && vin1 < 11.8 && vin2 < 11.8 && vin2 > 14.4) {
    digitalWrite(led_d13, HIGH);
  } 
  else {
    digitalWrite(led_d13, LOW);
  }
  delay(500);

Ryzen
(12 items)
CPU
Ryzen 5 2600X
Motherboard
MSI x470 Gaming Plus
GPU
MSI Armour RX 570 8GB OC
RAM
Team Group TDGED416G3000HC16CDC01 2x8GB 3000Mhz C16
Hard Drive
WD Black 500 GB NVMe
Power Supply
Rosewill Capstone 750
Cooling
Cheap 240 AIO
Case
Rosewill Rise
Operating System
Win 10 Pro
Keyboard
Microsoft Sidewinder x4
Mouse
Logitech G300s
Audio
Audio Technica M50xBT
▲ hide details ▲

Last edited by 5291Crash; 03-01-2018 at 02:28 AM.
5291Crash is offline  
post #3 of 4 (permalink) Old 03-01-2018, 04:38 AM
New to Overclock.net
 
Mrzev's Avatar
 
Join Date: Feb 2008
Location: Texas
Posts: 2,258
Rep: 96 (Unique: 76)
vout0-2 are calcuated before you read the voltage, so your actually using the voltage based on the previous iteration. You should move the read to the top so that the vouts get calculated after you get the reading.
Code:
void loop() {
  vout0 = (value * 3.98) / 1023.0; 
  vout1 = (value * 3.98) / 1023.0; 
  vout2 = (value * 3.98) / 1023.0; 
  value = analogRead(a0);

It depends on how you want to code it really. I like this approach better. Your doing your if else on the previous condition, leaving 4 possible options, and then you just set the values accordingly. A bit more optimized in this situation IMO.
Code:
if (vin0 < 14.4 && vin0 > 11.8) {
    digitalWrite(led_d11, HIGH);
    digitalWrite(led_d12, LOW);
    digitalWrite(led_d13, LOW);
  }
else if (vin1 < 11.8 && vin1 > 14.4) {
    digitalWrite(led_d11, LOW);
    digitalWrite(led_d12, HIGH);
    digitalWrite(led_d13, LOW);
  } 
  else if (vin2 < 11.8 && vin2 > 14.4){
    digitalWrite(led_d11, LOW);
    digitalWrite(led_d12, LOW);
    digitalWrite(led_d13, HIGH);
  }
  else {
    digitalWrite(led_d11, LOW);
    digitalWrite(led_d12, LOW);
    digitalWrite(led_d13, LOW);
  }
  delay(500);

Edit: You also can get more fancy by setting them all to low in the setup, and use a global variable to keep track of what was set last, and then before flipping the new, you flip the old off. By doing this your only flipping 1-2 leds instead of 3. You can also change it so that you can check to see if it is the same , prior to flipping them, so you can end up with 0-2 flips. But that just adds more work and stuff, and depending on the architecture, it may even take more cycles that way.




Last edited by Mrzev; 03-01-2018 at 04:47 AM.
Mrzev is offline  
Sponsored Links
Advertisement
 
post #4 of 4 (permalink) Old 03-01-2018, 07:41 PM - Thread Starter
New to Overclock.net
 
5291Crash's Avatar
 
Join Date: Dec 2004
Location: Landsowne, Ontario, Canada
Posts: 563
Rep: 26 (Unique: 26)
Quote: Originally Posted by Mrzev View Post
vout0-2 are calculated before you read the voltage . . .

It depends on how you want to code it really. . .

Edit: You also can get more fancy by . . .
Thanks for the input very much appreciated, I rearranged the vout's to the top. I then had to re adjust them to the current alignment to get them to all read the right voltages as displayed on the screen.

as for the output switching its only switching D11 from A0's input and ignoring the rest.

older code
Spoiler!


Time for bed haha
Thanks again for the pointers much appreciated
Joe

Edit #1:

Current code
Spoiler!


Now that i have added the serial bit its working as it should on the test board, but reads wrong on the serial port. I think the issue is on the test board its powered from the board, where as the USB provides power when on serial. Since its my understanding i can not power the board (Vin pin) and use USB at the same time. I'd have to look but i dont think i have a serial (DB9) to usb adapter handy to feed the i/o pins and ground to.


EDIT#2:

Decided to give it a go with USB and power on the Vin pin, and it didn't let out the majic smoke lol

I did sort the issue with USB voltages not showing right, its an issue with the onboard voltage regulator i'm guessing. as i noted that while on USB the VREF pin shows 3.8v, and while on External power its showing 4.1.
I have updated the default values for the resistors to the values i can measure, i need a better count rate meter (all 4 i have are 2000).

Managed to also get the real time clock working and displaying too.
Just need to get the specs for my current bridge and have them programmed in and all will be finished and ready to assemble a PCB and test.
Spoiler!

Ryzen
(12 items)
CPU
Ryzen 5 2600X
Motherboard
MSI x470 Gaming Plus
GPU
MSI Armour RX 570 8GB OC
RAM
Team Group TDGED416G3000HC16CDC01 2x8GB 3000Mhz C16
Hard Drive
WD Black 500 GB NVMe
Power Supply
Rosewill Capstone 750
Cooling
Cheap 240 AIO
Case
Rosewill Rise
Operating System
Win 10 Pro
Keyboard
Microsoft Sidewinder x4
Mouse
Logitech G300s
Audio
Audio Technica M50xBT
▲ hide details ▲

Last edited by 5291Crash; 03-02-2018 at 03:03 PM.
5291Crash is offline  
Reply

Quick Reply
Message:
Options

Register Now

In order to be able to post messages on the Overclock.net - An Overclocking Community forums, you must first register.
Please enter your desired user name, your email address and other required details in the form below.
User Name:
If you do not want to register, fill this field only and the name will be used as user name for your post.
Password
Please enter a password for your user account. Note that passwords are case-sensitive.
Password:
Confirm Password:
Email Address
Please enter a valid email address for yourself.
Email Address:

Log-in



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Show Printable Version Show Printable Version
Email this Page Email this Page


Forum Jump: 

Posting Rules  
You may post new threads
You may post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off