/********************************************************************* Powertester Measures 2 voltages and current from an equipment(Load), and logs the results on SD card. Control and read values from bluetooth. By Jony Silva Tue Jun 12 14:56:12 GMT 2018 *********************************************************************/ // Libraries to be included, non native libraries need to be included in the Makefile #include // Handles the connection and communications with the LCD display #include // Handles the SPI connection to the SD card #include // Handles communication routines with the SD card // Configuration of pins, insert here arduino pin numbers only(not fisical)---------------------------- #define v_batt 7 // Analog pin for the battery voltage #define volt_1 0 // Analog pin for voltage 1 #define volt_2 1 // Analog pin for voltage 2 #define load_line 17 // Line that turns load On or Off #define LEFT 16 // Button 1 will be function Left #define RIGHT 18 // Button 2 will be function Right #define ACT 19 // Button 3 will be function Action LiquidCrystal lcd(7, 6, 2, 3, 4, 5); // LCD screen pins, LiquidCrystal(rs, enable, d4, d5, d6, d7) //----------------------------------------------------------------------------------------------------- // Other configurations ------------------------------------------------------------------------------------ #define battery_volt 3 // Parameter position where battery voltage value is hold #define voltage_1 0 // Parameter position where voltage one value is hold #define voltage_2 1 // Parameter position where voltage two value is hold #define numOfScreens 7 // Number of screen menus, select here and rearrange String screens File myFile; //---------------------------------------------------------------------------------------------------------- // Macros -------------------------------------------------------- #define rLEFT digitalRead(LEFT) // Read button Left #define rRIGHT digitalRead(RIGHT) // Read button Right #define rACT digitalRead(ACT) // Read button Action #define sd_not_in 0 // SD card is not inserted #define sd_in 1 // SD card is inserted #define file_fail 2 // Can't write to file #define writing 3 // Write on the sd card #define load_off 0 // Turn off the load #define load_on 1 // Turn on the load #define off 0 // off is always zero #define on 1 // on is always one #define no 0 // no is always zero #define yes 1 // yes is alyays one //---------------------------------------------------------------- // Variables -------------------------------------------------------------------------------------------------------------- bool sd_rw = off; // Holds the state of read/write of the card bool load_status = load_off; // Holds the state of on/off of the load bool sd_inserted = no; // Holds the stats if sd card is in or not int sd_status = sd_not_in; // Holds information about the sd card int currentScreen = 0; // Current display menu // String with the menus to be displayed String screens[numOfScreens][2] = {{"Voltage 1","Volts"}, {"Voltage 2","Volts"}, {"Load current","Amps"},{"Batt Voltage","volts"}, {"SD Logging", ""}, {"Load", ""}, {"SD card", ""}}; String parameters_sd[2] = {"No","Yes"}; // String to display the sd card logging String parameters_load[2] = {"Off","On"}; // String to display the load state String sd_card[4] = {"Card missing","Card inserted","File Write fail","Writing..."}; // String to display the sd card state float parameters[4]; // Parameters of the several voltages and current float denominator; int resistor1 = 22000; // Resistor one of voltage divider int resistor2 = 2200; // Resistor two of voltage divider // ------------------------------------------------------------------------------------------------------------------------ // Function declarations -------------------------------------------------- void menuState(void); // Read buttons and update menu void printScreen (void); // Print menus and variables on screen float volt_pin (int pin); // Read and display voltage //------------------------------------------------------------------------- void setup() { pinMode(LEFT, INPUT); // Button left is an input pinMode(RIGHT, INPUT); // Button right is an input pinMode(ACT, INPUT); // Button act is an input pinMode(load_line, OUTPUT); // load_line is an output lcd.begin(16, 2); // Voltage divider --> Vout = Vin * R2 / R1 + R2 denominator = (float)resistor2 / (resistor1 + resistor2); // initialize timer1 --------------------------------------- noInterrupts(); // disable all interrupts TCCR1A = 0; TCCR1B = 0; TCNT1 = 0; OCR1A = 9000; // Load value to compare TCCR1B |= (1 << WGM12); // CTC mode TCCR1B |= (1 << CS10); // 64 prescaler TCCR1B |= (1 << CS11); // TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt interrupts(); // enable all interrupts // ---------------------------------------------------------- if (SD.begin()) // Initiate SD card { sd_status = sd_in; // If sd card is initiated successfully change variable sd_in sd_inserted = yes; // and change variable sd_inserted to yes } else { sd_status = sd_not_in; // If sd card is not initiated change variable to sd_not_in sd_inserted = no; // and change variable sd_inserted to no } } // Timer compare interrupt service routine -- ISR(TIMER1_COMPA_vect) { menuState(); // Read buttons act accordingly and update menus digitalWrite(load_line, load_status); // Turn load on or off depending on the load_status } //------------------------------------------- void loop() { parameters[battery_volt] = volt_pin(v_batt); // Update Battery voltage value parameters[voltage_1] = volt_pin(volt_1); // Update voltage one value parameters[voltage_2] = volt_pin(volt_2); // Update voltage two value if (sd_inserted == no) // If sd_rw value is turned on { sd_status = sd_not_in; } else if (sd_rw == on) { myFile = SD.open("measure.txt", FILE_WRITE); // Open file measure.txt for writing if (myFile) // if succeds { myFile.print("Batt voltage, "); myFile.println(volt_pin(v_batt)); // Write to card battery voltage myFile.print("Voltage one, "); myFile.println(volt_pin(volt_1)); // Write to card voltage one myFile.print("Voltage two, "); myFile.println(volt_pin(volt_2)); // Write to card voltage two myFile.println(""); // Write to card an empty line myFile.close(); // Close file sd_status = writing; } else { sd_status = file_fail; } } else { sd_status = sd_in; } printScreen(); // Refresh screen and print current menu and values delay(5000); // Repeat the main loop every 5 seconds } void menuState() { if (!rRIGHT) { if (currentScreen == (numOfScreens - 1)) { currentScreen = 0; } else { currentScreen++; } while (!rRIGHT); // Check if button is still pressed do nothing printScreen(); // Refresh screen and print current menu and values } if (!rLEFT) { if (currentScreen == 0) { currentScreen = (numOfScreens - 1); } else { currentScreen--; } while (!rLEFT); // Check if button is still pressed do nothing printScreen(); // Refresh screen and print current menu and values } if (!rACT) { if (currentScreen == 4) { sd_rw = !sd_rw; } if (currentScreen == 5) { load_status = !load_status; } while (!rACT); // Check if button is still pressed do nothing printScreen(); // Refresh screen and print current menu and values } } void printScreen() { lcd.clear(); lcd.print(screens[currentScreen][0]); lcd.setCursor(0,1); if (currentScreen == 4) { lcd.print(parameters_sd[sd_rw]); } else if (currentScreen == 5) { lcd.print(parameters_load[load_status]); } else if (currentScreen == 6) { lcd.print(sd_card[sd_status]); } else { lcd.print(parameters[currentScreen]); lcd.print(" "); lcd.print(screens[currentScreen][1]); } } float volt_pin(int pin) { float voltage; voltage = analogRead(pin); // Obtain RAW voltage data voltage = (voltage / 1024) * 3.3; // Convert to actual voltage voltage = voltage / denominator; // Convert to voltage after divider return voltage; }