Overclock.net - An Overclocking Community

Overclock.net - An Overclocking Community (https://www.overclock.net/forum/)
-   Coding and Programming (https://www.overclock.net/forum/142-coding-programming/)
-   -   Arduino code help, way out of my depth (https://www.overclock.net/forum/142-coding-programming/1665561-arduino-code-help-way-out-my-depth.html)

5291Crash 02-28-2018 09:54 PM

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

5291Crash 03-01-2018 02:13 AM

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);


Mrzev 03-01-2018 04:38 AM

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.

5291Crash 03-01-2018 07:41 PM

Quote:

Originally Posted by Mrzev (Post 26860497)
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!


All times are GMT -7. The time now is 10:05 PM.

Powered by vBulletin® Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.

User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2019 DragonByte Technologies Ltd.
vBulletin Security provided by vBSecurity (Pro) - vBulletin Mods & Addons Copyright © 2019 DragonByte Technologies Ltd.

vBulletin Optimisation provided by vB Optimise (Pro) - vBulletin Mods & Addons Copyright © 2019 DragonByte Technologies Ltd.