- /*Emma 5's Light
- *Comprehensive integrated power management.
- *This module will eventually take commands from Emma to change bus topology.
- *Emma may also request the most recent averages for current and voltage.
- *Luke Dyson
- *Spring 2010
- */
- //These definitions initialize the default values of the bus switches as not to interfere with the hardware defaults.
- //The stipulation here is that both batteries will be tied to the "quiet" bus (Bus A).
- //Since here we use solid state switches we will respond to boolean values appropriately.
- //Default solid state bus switch topology (Both batteries tied to quiet bus).
- #define swState1A 1
- #define swState2A 1
- #define swState1B 0
- #define swState2B 0
- //Pin assignments for analog inputs.
- #define analogVPin1 1
- #define analogIPin1 2
- #define analogVPin2 3
- #define analogIPin2 4
- //Analog read delay value (ms).
- #define analogDelay 3
- //Default Pins for bus switch controls.
- //Do not use pin 13 because it will blink once on reset ALWAYS.
- #define sw1A 9
- #define sw1B 10
- #define sw2A 11
- #define sw2B 12
- //Change this variable to affect the number of readings used in an average of current or voltage.
- #define bufferSize 10
- //485 bus parameters.
- #define rx 2
- #define tx 3
- #define dataSize 4
- #define readTimeOut 500000 //define how long the readBus function has to run in microseconds
- //485 bus global variables.
- byte dataIn[dataSize];
- byte dataOut[dataSize];
- byte tempByte;
- boolean dataFound;
- boolean dataToWrite;
- unsigned long readStart;
- //Variables to store millisecond counts.
- long currentMillis = 0;
- long previousMillis = 0;
- long loopTime = 10;
- //Variable to hold number of valid readings performed by the ADC.
- int Reads = 0;
- //Arrays to hold voltage and current readings with least recently used update strategy.
- //Arrays to store electrical current measurements.
- int iBufferL[bufferSize];
- int iBufferQ[bufferSize];
- //Arrays to store voltage measurements.
- int vBuffer1[bufferSize];
- int vBuffer2[bufferSize];
- //Constants of proportionality for voltage different on hall sensor to true current (TBD).
- int c = 1;
- int d = 1;
- //One array for each battery. First element in array is state of quiet bus switch (VN920) the second is the state of the noisy bus (MOSFET).
- //By default battery 1 is tied to the quiet bus.
- int batt1State[] = {0, 0};
- //By default battery 2 is tied to quiet bus.
- int batt2State[] = {0, 0};
- //One array for each battery. Holds average voltage and current (in array respectively).
- int batt1Avg[] = {0, 0};
- int batt2Avg[] = {0, 0};
- //Flag to remember which battery was tied to the drive train.
- int useFlag;
- //Setup function runs once.
- void setup() {
- //485 bus initialization code.
- Serial.begin(19200);
- pinMode(rx, OUTPUT);
- pinMode(tx, OUTPUT);
- //both HIGH to transmit
- dataFound = false;
- dataToWrite = false;
- digitalWrite(rx, LOW);
- digitalWrite(tx, LOW);
- //Store present number of elapsed milliseconds.
- currentMillis = millis();
- //Initialize output pins for bus switches.
- pinMode(sw1A, OUTPUT);
- pinMode(sw1B, OUTPUT);
- pinMode(sw2A, OUTPUT);
- pinMode(sw2B, OUTPUT);
- //Initialize Power Bus Configuration.
- digitalWrite(sw1A, HIGH);
- digitalWrite(sw2A, HIGH);
- //Update battery bus indicator.
- batt1State[0] = 1;
- batt1State[0] = 1;
- //This will become a future problem with timer overflow to be addressed later.
- while(millis() < (currentMillis + loopTime)){
- }
- }
- void loop() {
- //Store time at begining of loop.
- currentMillis = millis();
- //Reset array position for next reading to reflect least recently used.
- if(Reads == bufferSize){
- Reads = 0;
- }
- //Take readings of voltage off of both batteries.
- //Factor of 4 is to compensate for the 4-to-1 voltage divider installed on all analog inputs for safety.
- vBuffer1[Reads] = 4*analogRead(analogVPin1);
- delay(analogDelay);
- vBuffer2[Reads] = 4*analogRead(analogVPin2);
- delay(analogDelay);
- //Constants C and D proportionality between voltage deflection on hall sensor and current (TBD) on each bus.
- iBufferL[Reads] = 4*c*analogRead(analogIPin1);
- delay(analogDelay);
- iBufferQ[Reads] = 4*d*analogRead(analogIPin2);
- Reads++;
- readBus(dataIn);
- if(dataFound){
- //someone said something to you
- //carry on accordingly
- if(dataIn[1]==B10101000){
- //Swap buses.
- swapBus();
- }else if(dataIn[1]==B10101001){
- //We are being polled for data.
- //Send two messages, one for each battery, last two fields are average voltage and current respectively.
- //Second field is command field.
- sendPowerData();
- }else if(dataIn[1]==B10101010){
- //Make power available to the noisy bus.
- enablePower();
- }
- }
- dataToWrite = true;
- //if you have something to say, simply fill it into the 'dataOut' array and set dataToWrite=true
- if(dataToWrite){
- writeBus(dataOut);
- }
- //Sample code for printing to console
- //Used to test Hall Sensors and Arduino ADC
- /* Serial.println("Voltage battery 1:");
- Serial.println(vStack1[Reads]);
- Serial.println("Voltage battery 2:");
- Serial.println(vStack2[Reads]);
- Serial.println("Current battery 1:");
- Serial.println(iStack1[Reads]);
- Serial.println("Current battery 2:");
- Serial.println(iStack2[Reads]);*/
- //This will become a future problem with timer overflow to be addressed later..//////
- while(millis() < (currentMillis + loopTime)){
- }
- }
- void swapBus(){
- if(batt2State[1]==1){
- //If battery two is on the loud bus swap it with 1.
- batt2State[1]=0;
- digitalWrite(sw2B, LOW);
- //Switch battery two over to quiet bus.
- batt2State[0]=1;
- digitalWrite(sw2A, HIGH);
- //Switch battery one off of quiet bus...
- batt1State[0]=0;
- digitalWrite(sw1A, LOW);
- //...and onto the loud bus.
- batt1State[1]=1;
- digitalWrite(sw1B, HIGH);
- }else{
- //If battery one is on the loud bus swap it with 2.
- batt1State[1]=0;
- digitalWrite(sw1B, LOW);
- //Switch battery one over to quiet bus.
- batt1State[0]=1;
- digitalWrite(sw1A, HIGH);
- //Switch battery two off of quiet bus...
- batt2State[0]=0;
- digitalWrite(sw2A, LOW);
- //...and onto the loud bus.
- batt2State[1]=1;
- digitalWrite(sw2B, HIGH);
- //Else it's battery two and we need to swap it with battery 1.
- }
- }
- void sendPowerData(){
- }
- void enablePower(){
- //Disconnect battery two from the quiet bus.
- batt2State[0] = 0;
- digitalWrite(sw2A, LOW);
- //Connect battery two to the noisy bus.
- batt2State[1] = 1;
- digitalWrite(sw2B, HIGH);
- }
- void writeBus(byte *dataOut){
- digitalWrite(rx, HIGH);
- digitalWrite(tx, HIGH);
- delayMicroseconds(1);
- for(int i=0; i<dataSize; i++){
- Serial.write(dataOut[i]);
- }
- dataToWrite = false;
- //stop writing
- digitalWrite(rx, LOW);
- digitalWrite(tx, LOW);
- delayMicroseconds(1);
- }
- void readBus(byte *dataIn){
- readStart = micros();
- dataFound = false;
- while(Serial.available()>0 && (micros()-readStart)<readTimeOut){ //while there are bytes available in the serial buffer (128 max)...
- tempByte = Serial.read(); //read them into 'tempByte'...
- if(addressCheck(tempByte) && (micros()-readStart)<readTimeOut){ //if tempByte is an address you are looking for...
- while(Serial.available()<3 && (micros()-readStart)<readTimeOut){ //wait for the other bytes in the message to arrive or the whole group of 4 bytes will be lost
- delayMicroseconds(1); //they will probably be there anyway
- }
- dataFound = true;
- dataIn[0] = tempByte;
- for(int i=1; i<dataSize; i++){
- dataIn[i] = Serial.read();
- }
- }
- }
- }
- boolean addressCheck(byte x){
- //fill in this switch statement with whatever addresses you want to pay attention to
- switch (x){
- case B00000011: // normally an address you pay attention to would go here (Emma's power subprocessor address is 3)
- return true;
- default:
- return false;
- }
- }