Ryan Tseng
/
Display
Revision 0:b669c97da2c0, committed 2012-06-18
- Comitter:
- kagelump
- Date:
- Mon Jun 18 16:47:00 2012 +0000
- Commit message:
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/KS0108.lib Mon Jun 18 16:47:00 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/kagelump/code/KS0108/#14a7c22dfbe8
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/calsolimage.h Mon Jun 18 16:47:00 2012 +0000 @@ -0,0 +1,135 @@ +#ifndef IMAGE_H +#define IMAGE_H + +unsigned char pic[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x80,0x40,0x40,0x40,0x40, +0x40,0x40,0x80,0x00,0x80,0x40,0x40,0x40, +0x40,0x40,0x40,0x80,0x00,0x80,0x40,0x40, +0x40,0x40,0x40,0x40,0x80,0x00,0x80,0x40, +0x40,0x40,0x40,0x40,0x40,0x80,0x00,0x80, +0x40,0x40,0x40,0xC0,0x40,0x00,0x00,0x80, +0xC0,0xC0,0xC0,0xE0,0xE0,0xE0,0xE0,0xE0, +0xC0,0xC0,0x80,0x80,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x3F,0x40,0x40,0x40,0x40, +0x40,0x40,0x3F,0x00,0x3F,0x40,0x40,0x40, +0x40,0x40,0x40,0x3F,0x00,0x3F,0x40,0x40, +0x40,0x40,0x40,0x40,0x3F,0x00,0x3F,0x40, +0x40,0x40,0x40,0x40,0x40,0x3F,0x00,0x9F, +0xC4,0xF2,0xF9,0xFC,0xFE,0x7F,0x3F,0x1F, +0x07,0x07,0x03,0x03,0x03,0x01,0x03,0x03, +0x07,0xCF,0xCF,0xCF,0xC6,0xC6,0xC0,0xC0, +0xC0,0xC0,0x80,0x80,0xC0,0xE0,0xF0,0xF0, +0xF8,0xF8,0xF8,0xF8,0x58,0x00,0xA0,0xF8, +0xF8,0xF8,0x78,0x08,0x00,0x00,0x00,0x00, +0x80,0xC0,0xF0,0xF8,0xF8,0x78,0x78,0x78, +0x38,0x38,0x78,0x38,0x00,0x80,0xC0,0xE0, +0xF0,0xF8,0x78,0x78,0x78,0x38,0x78,0xF8, +0xF0,0xF0,0xC0,0x00,0x00,0x00,0x00,0xC0, +0xE8,0xF8,0xF8,0xF8,0x38,0x00,0x00,0x00, +0x00,0x00,0x00,0x7E,0x81,0x81,0x81,0x81, +0x81,0x81,0x7E,0x00,0x7E,0x81,0x81,0x81, +0x81,0x81,0x81,0x7E,0x00,0x7E,0x81,0x81, +0x81,0x81,0x81,0x81,0x7E,0x00,0x7E,0x81, +0x81,0x81,0x61,0x1D,0xC3,0xF8,0xFE,0xFF, +0xFF,0x3F,0x07,0x03,0x00,0x00,0x00,0x00, +0x00,0x18,0x18,0x18,0xD8,0xD8,0xD8,0xD8, +0xD8,0xD8,0x58,0x18,0xE8,0xF0,0xF8,0xFC, +0x3F,0x3F,0x1F,0x0F,0x03,0x03,0xF1,0xFF, +0xFF,0xFF,0x3F,0x07,0xF0,0xFE,0xFF,0xFF, +0x5F,0x07,0x00,0x00,0x00,0x00,0x00,0x00, +0x03,0x1F,0xFF,0xFF,0xFF,0x80,0x00,0x00, +0x00,0x00,0xE0,0xF8,0xFF,0xFF,0x3F,0x0F, +0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xC0, +0xFF,0xFF,0xFF,0x3F,0x00,0xC0,0xFC,0xFF, +0xFF,0xFF,0x17,0x01,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0xFC,0x02,0x02,0x02,0x02, +0x02,0x02,0xFC,0x00,0xFC,0x02,0x02,0x02, +0x02,0x02,0x02,0xFC,0x00,0xFC,0x02,0x02, +0x02,0x02,0x02,0x02,0xFC,0x00,0xFC,0x02, +0x02,0xFE,0x00,0x74,0xFF,0xFF,0xFF,0xFF, +0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x40,0x78,0x78,0x78,0x78,0x78,0x78,0x78, +0x78,0xF8,0xFD,0xFF,0xFF,0x7F,0x7F,0x79, +0x78,0x78,0x78,0x78,0xF8,0xFF,0xFF,0xFF, +0x3F,0x03,0xF0,0xFD,0xFF,0xFF,0xBF,0x83, +0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80, +0x80,0xC0,0xEF,0xFF,0xFF,0xFF,0x78,0x00, +0x00,0x11,0xFF,0xFF,0xFF,0xF1,0xC0,0x80, +0x80,0x80,0xC0,0xC0,0xF0,0xF8,0xFE,0x7F, +0x3F,0x0F,0x01,0xC0,0xF4,0xFF,0xFF,0xFF, +0x8F,0x80,0x80,0x80,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0xF8,0x05,0x05,0x05,0x05, +0x05,0x05,0xF8,0x00,0xF8,0x05,0x05,0x05, +0x05,0x05,0x05,0xF8,0x00,0xF8,0x05,0x05, +0x05,0x05,0x05,0x05,0xF8,0x00,0xF8,0x05, +0x05,0x05,0x38,0xC0,0x0F,0x3F,0x7F,0xFF, +0xFC,0xF0,0xE0,0xC0,0xE0,0xE0,0xE0,0xE0, +0xE0,0xF0,0xF8,0xFC,0x78,0x70,0x00,0x00, +0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00, +0x00,0x00,0x00,0x06,0x07,0x07,0x07,0x01, +0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07, +0x07,0x07,0x00,0x04,0x07,0x07,0x07,0x07, +0x07,0x07,0x07,0x03,0x03,0x01,0x00,0x00, +0x00,0x00,0x00,0x01,0x03,0x07,0x07,0x07, +0x07,0x07,0x07,0x03,0x03,0x01,0x00,0x00, +0x00,0x00,0x02,0x07,0x07,0x07,0x07,0x07, +0x07,0x07,0x07,0x03,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x01,0x02,0x02,0x02,0x02, +0x02,0x02,0x01,0x00,0x01,0x02,0x02,0x02, +0x02,0x02,0x02,0x01,0x00,0x01,0x02,0x02, +0x02,0x02,0x02,0x02,0x01,0x00,0x01,0x02, +0x02,0x02,0x02,0x02,0x03,0x02,0x00,0x00, +0x01,0x01,0x03,0x03,0x03,0x03,0x03,0x03, +0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Jun 18 16:47:00 2012 +0000 @@ -0,0 +1,381 @@ +// Display Test +#include "KS0108.h" +#include "calsolimage.h" +#include "MyPhone_20.h" +#include "MyPhone_40.h" +#include "rtos.h" + +// Declare each of the things you're going to use + +// The display +KS0108 display(p23,p21,p22,p20,p24,p25,p17,p18,p19,p30,p29,p28,p27,p26); +// The button on the breadboard +DigitalIn topButton(p13); +// For printing things to the computer +Serial pc(USBTX,USBRX); + +// Timers +Timer timer; +Timer testTimer; + +//Methods +void readFromCAN(); +void setupScreen(); +void updateBattery(int newVoltage); +void updateBatteryGraphic(int newPercentage, int percentage); +void printCenteredInt(int newInt, int oldInt, int startX, int startY, int charWidth, int charHeight, int charSpacing, int maxDigits); +void printCenteredInt(int newInt, int oldInt, int leftLimit, int rightLimit, int startY, int charWidth, int charHeight, int charSpacing, int maxDigits); +void printRightJustifiedInt(int newInt, int oldInt, int startX, int startY, int charWidth, int charHeight, int charSpacing, int maxDigits); + +// Constants + +//Maximum voltage for battery = 151.2 V (4.2V per cell, 36 cells total) +const double MaxVoltage = 151.2; +//Minimum voltage for battery = 108 V (3V per cell, 36 cells total) +const double MinVoltage = 108; + +// Mutex and screen state +Mutex screen_mutex; +CAN can(p9, p10); +int demo = 0; + + +//Speed: int from 0 to 999, in mph +int speed = 0, newSpeed = 0; +//Voltage: int from MinVoltage to MaxVoltage, in volts +int voltage = MinVoltage, newVoltage = MinVoltage; +//Current: int from 0 to 9999, in milliAmps +int amperage = 0, newAmperage = 0; + + +//Union type to make float to char conversion easier (used to read CAN messages) +typedef union _data +{ + float f[2]; + char s[8]; +} floatchar; + +//Union type to make int to char conversion easier (used to read CAN messages) +typedef union _data2 +{ + uint16_t i[4]; + char s[8]; +} intchar; + + +/* Input thread - Modifies state variables based on input */ +void input_runner(void const *argument) { + while (true) { + // If top button is pressed, don't accept other input + if (!topButton) { + // Debounce wait + Thread::wait(100); + if (!topButton) { + screen_mutex.lock(); + demo++; + if (demo > 1) { + demo = 0; + } + screen_mutex.unlock(); + } + // Don't accept other input while button is pressed + while(!topButton) { + Thread::wait(100); + } + } + } +} + + +// This is where your programs starts running +int main() +{ + // Initialize variables** + int current_demo = demo; + topButton.mode(PullUp); + // Display CalSol logo + display.FullScreenBMP(pic); + Thread::wait(200); + + timer.start(); + + // Start the button thread + Thread button_thread(input_runner); + + // Main thread + while(1) { + // First, check if the state has changed, if so, wipe the screen + int changed = 0; + screen_mutex.lock(); + if (current_demo != demo) + { + changed = 1; + } + current_demo = demo; + screen_mutex.unlock(); + + // Wipe the screen + if (changed) + { + display.ClearScreen(); + changed = 0; + } + + // Now run the actual program + switch(current_demo) + { + // Demo 0: Just display the CalSol logo + case 0: + if(timer.read_ms() > 500) + { + display.FullScreenBMP(pic); + timer.reset(); + } + break; + + // Demo 1: Display a mock speedometer, with battery level + case 1: + //Initialize variables + speed = newSpeed = 60; + amperage = newAmperage = 900; + voltage = newVoltage = MaxVoltage; + + setupScreen(); + testTimer.start(); + + //Display values as they are being changed + while (true) + { + /* This part tests the printing + + //Randomly selects values between appropriate ranges. + speed = (int)(rand()%200); + amperage = (int)(rand()%1000); + voltage = (int)(rand()%100); + + //Changes values from 1 to 3 or 4 digits to test proper spacing and erasing with changing num of digits + if (testTimer.read_ms()%1000 == 0) + { + switch ((testTimer.read_ms()/1000)%4) + { + case 0: //1 digit + newSpeed = (int)(rand()%9)+1; + newAmperage = (int)(rand()%9)+1; + break; + case 3: //2 digits + newSpeed = (int)(rand()%90)+10; + newAmperage = (int)(rand()%90)+10; + break; + case 2: //3 digits + newSpeed = (int)(rand()%900)+100; + newAmperage = (int)(rand()%900)+100; + break; + case 1: //4 digits + newSpeed = (int)(rand()%90)+100; + newAmperage = (int)(rand()%900)+1000; + break; + default: break; + } + }*/ + + //Keeps screen from updating too much + if (testTimer.read_ms()%1000==0) + { + /* More printing testing + + //Randomly increases or decreases values within a small range + newSpeed += (int)((rand()%5)-2); + newAmperage += (int)((rand()%21)-10); + newVoltage += (int)((rand()%3)-1); + + //Keeps voltage between allowed values + if (newVoltage < MinVoltage || newVoltage > MaxVoltage) + newVoltage = MaxVoltage; + */ + + readFromCAN(); + + updateBattery(newVoltage); + + //Updates speed + display.SelectFont(MyPhone_40, BLACK, ReadData); + printCenteredInt(newSpeed, speed, 12, 16, 15, 23, 1, 3); + speed = newSpeed; + + //Updates amperage + display.SelectFont(MyPhone_20, BLACK, ReadData); + printCenteredInt(newAmperage, amperage, 76, 40+8, 8, 11, 1, 4); + amperage = newAmperage; + } + } + break; + default: break; + } + } +} + +void setupScreen() +{ + //Draws grid lines to separate the screen. + //Dimensions: (Speed) 70x64, (Battery) 57x42, (Amperage) 57x22 + display.HLineShort(71, 42, 57, BLACK); + display.VLineShort(71, 0, 64, BLACK); + + //This covers the stray black pixel... + display.SetPixel(71-5, 42, WHITE); + + //Draws the outline for battery graphic. Dimensions: 40x24, 4x8 + display.RoundRectangle(82, 4, 40, 24, 4, BLACK); + display.EmptyRectangle(78, 12, 78+4, 12+8, BLACK); + + //Prints MPH + display.SelectFont(System5x7, BLACK, ReadData); + display.GotoXY(26, 48); + display.PrintString("MPH"); + + //Print mAmp + display.SelectFont(System5x7, BLACK, ReadData); + display.GotoXY(114, 24+24); + display.PrintString("mA"); + + //Prints the percent sign + display.GotoXY(108, 24+8); + display.PrintString("%"); + + //Draws initial shaded box for battery + display.FullRectangle(86+(int)(((double)(100-((newVoltage - MinVoltage)/(MaxVoltage - MinVoltage)*100))/100.0)*32), 4+4, 86+32, 4+24-4, BLACK); +} + +//This exists to fix the problem with the percentage printing that was occuring for unknown reasons. +//Writes an int to the screen right-justified over another int. +void printRightJustifiedPercentage(int newInt, int oldInt, int startX, int startY, int charWidth, int charHeight, int charSpacing, int maxDigits) +{ + for (int digits = maxDigits; digits > 0; digits--) + { + if (newInt >= (int)pow(10.0, digits-1)) + { + //Instead of checking if digits need to be erased, all digits will be erased + //Erases digits that will not be covered by new text. + display.FullRectangle(startX, startY, startX + (charWidth+charSpacing) * (maxDigits - digits), startY + charHeight, WHITE); + display.GotoXY(startX + (charWidth+charSpacing) * (maxDigits - digits), startY); + //Break out of loop. + digits = -1; + } + } + display.PrintNumber(newInt); +} + +//Writes an int to the screen center-justified over another int. +void printCenteredInt(int newInt, int oldInt, int startX, int startY, int charWidth, int charHeight, int charSpacing, int maxDigits) +{ + for (int digits = maxDigits; digits > 0; digits--) + { + //If current value has "digits" number of digits + if (newInt >= (int)pow(10.0, digits-1)) + { + //If previous value had more digits than current value + if (oldInt >= (int)pow(10.0, digits)) + { + //Erases all possible digits that could be on screen. + //**First parameter should logically be startX, but it starts erasing 1 pixel too far to the right for some reason. ??? + display.FullRectangle(startX-1, startY, startX + maxDigits*(charWidth+charSpacing), startY + charHeight, WHITE); + } + display.GotoXY(startX + 0.5*((maxDigits - digits)*charWidth + (maxDigits - digits - 1)*charSpacing), startY); + //Break out of loop. + digits = -1; + } + } + display.PrintNumber(newInt); +} + +//Updates the battery graphic and prints corresponding percentage or voltage. +void updateBattery(int newVoltage) +{ + //These are needed for the battery graphic, even if the values won't be displayed. + int percentage = (voltage - MinVoltage)/(MaxVoltage - MinVoltage)*100; + int newPercentage = (newVoltage - MinVoltage)/(MaxVoltage - MinVoltage)*100; + + //This line fixes the printing problem with the percentage that was caused by drawing shaded rectangle. Might have something to do with the method WriteInstruction(int, int) used by both methods. + display.SetPixel(88, 32, WHITE); + + // ** Problem: after a while of letting it run, sometimes a 0 will show up 1 pxl to the right of the hundreds place. But it gets erased when voltage drops enough + //Prints percentage + display.SelectFont(System5x7, BLACK, ReadData); + printRightJustifiedPercentage(newPercentage, percentage, 88, 32, 5, 7, 1, 3); + + //Prints voltage -- currently NOT IN USE + /*display.SelectFont(System5x7, BLACK, ReadData); + display.GotoXY(108, 24+8); + display.PrintString("V"); + display.SelectFont(System5x7, BLACK, ReadData); + printRightJustifiedInt(newVoltage, voltage, 88, 32, 5, 7, 1, 3);*/ + + updateBatteryGraphic(newPercentage, percentage); + + percentage = newPercentage; + voltage = newVoltage; +} + +//Changes shaded area of graphic to reflect current battery level. Dimensions 32x16 +void updateBatteryGraphic(int newPercentage, int percentage) +{ + //Stores x-coordinates of shaded part of battery. + int barX = 86+(int)(((double)(100-percentage)/100.0)*32); + int newBarX = 86+(int)(((double)(100-newPercentage)/100.0)*32); + + //Draws increase in percentage. + if (newBarX < barX) + { + display.FullRectangle(newBarX, 4+4, barX, 4+24-4, BLACK); + } + //Draws decrease. + else + { + display.FullRectangle(86, 4+4, newBarX, 4+24-4, WHITE); + } +} + +//***This method has NOT BEEN TESTED. + +//Gets information about speed, voltage, current, and battery life through CAN. +void readFromCAN() +{ + const int speedID = 0x403; + const int voltageAmperageID = 0x523; + + //Gets message from CAN. + CANMessage msg; + can.read(msg); + int id = msg.id; + + switch (id) + { + case voltageAmperageID: //contains four messages: voltage 1 and 2 in volts, current 1 and 2 in mA. each is an int (2 bytes) + + //Read & store amperage value. + intchar amp_data; + for (int i = 0; i < 2; i++){ + amp_data.s[i] = msg.data[i]; + } + amperage = amp_data.i[0]; //***is this correct? + + //Read & store voltage/battery life value. + floatchar volt_data; + for (int i = 0; i < 2; i++){ + volt_data.s[i] = msg.data[i+4]; + } + voltage = volt_data.f[0]; //***should this be reading voltage 1 or voltage 2? (volt1.f[0 or 1]) + break; + + case speedID: + //** This packet actually contains motor velocity in rpm as well as vehicle velociy in m/s. How do I get only the second part? + floatchar speed_data; + for (int i = 0; i < 4; i++) { + speed_data.s[i] = msg.data[i]; + } + //Conversion factor: 1 m/s = 2.23693629 mph + speed = (speed_data.f[2])*2.23693629; //** should this be a combination of f[2] and f[3]? + break; + default: break; + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Jun 18 16:47:00 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/078e4b97a13e