]> git.defcon.no Git - rctxduino/blobdiff - source/RCTXDuino/RCTXDuino.pde
Added debug/status display of DR switches to display/UI
[rctxduino] / source / RCTXDuino / RCTXDuino.pde
index a6769d68098f31912370690d83dc3bda6ce671af..1afb5ea66db2dfa7184ce33b5f5ac159f8c60540 100644 (file)
@@ -1,4 +1,8 @@
-#include <LiquidCrystal.h>
+// No longer using HD44780-comaptible display,
+// Moving to a brand new world of dot-matrix display tech!
+// Using LCD library from http://code.google.com/p/pcd8544/
+#include <PCD8544.h>
+
 #include <TimerOne.h>
 #include <EEPROM.h>
 
@@ -71,8 +75,8 @@ volatile model_t model;
 unsigned char current_model; // Using uchar to spend a single byte of mem..
 
 // ----------------- Display related stuffs --------------------
-LiquidCrystal lcd( 12, 11, 10,     6,  7,  8,  9);
-// Parameters are: rs, rw, enable, d4, d5, d6, d7 pin numbers.
+PCD8544 lcd( 8,  9,   10, 11,    12);
+// Param:   sclk, sdin, dc, reset, sce
 
 // ----------------- PPM related stuffs ------------------------
 // The PPM generation is handled by Timer0 interrupts, and needs
@@ -164,130 +168,6 @@ unsigned long prev_loop_time;
 unsigned long avg_loop_time;
 unsigned long t;
 #endif
-// -----------------------LCD--------------------------
-
-
-#define PIN_SCE   7 //Pin 3 on LCD
-#define PIN_RESET 6 //Pin 4 on LCD
-#define PIN_DC    5 //Pin 5 on LCD
-#define PIN_SDIN  4 //Pin 6 on LCD
-#define PIN_SCLK  3 //Pin 7 on LCD
-
-//The DC pin tells the LCD if we are sending a command or data
-#define LCD_COMMAND 0 
-#define LCD_DATA  1
-
-//You may find a different size screen, but this one is 84 by 48 pixels
-#define LCD_X     84
-#define LCD_Y     48
-
-//This table contains the hex values that represent pixels
-//for a font that is 5 pixels wide and 8 pixels high
-static const byte ASCII[][5] = {
-  {0x00, 0x00, 0x00, 0x00, 0x00} // 20  
-  ,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
-  ,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
-  ,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
-  ,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
-  ,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
-  ,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
-  ,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
-  ,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
-  ,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
-  ,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
-  ,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
-  ,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
-  ,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
-  ,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
-  ,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
-  ,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
-  ,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
-  ,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
-  ,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
-  ,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
-  ,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
-  ,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
-  ,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
-  ,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
-  ,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
-  ,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
-  ,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
-  ,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
-  ,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
-  ,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
-  ,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
-  ,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
-  ,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
-  ,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
-  ,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
-  ,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
-  ,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
-  ,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
-  ,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
-  ,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
-  ,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
-  ,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
-  ,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
-  ,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
-  ,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
-  ,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
-  ,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
-  ,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
-  ,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
-  ,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
-  ,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
-  ,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
-  ,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
-  ,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
-  ,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
-  ,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
-  ,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
-  ,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
-  ,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
-  ,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c \
-  ,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
-  ,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
-  ,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
-  ,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
-  ,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
-  ,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
-  ,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
-  ,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
-  ,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
-  ,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
-  ,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
-  ,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
-  ,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
-  ,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j 
-  ,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
-  ,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
-  ,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
-  ,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
-  ,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
-  ,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
-  ,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
-  ,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
-  ,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
-  ,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
-  ,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
-  ,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
-  ,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
-  ,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
-  ,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
-  ,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
-  ,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
-  ,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
-  ,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
-  ,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ~
-  ,{0x78, 0x46, 0x41, 0x46, 0x78} // 7f DEL
-};
-
-
-
-
-
-
-
 
 // ---------- CODE! -----------------------------------
 
@@ -300,11 +180,14 @@ void setup(){
   pinMode(4, OUTPUT);    // s2
   pinMode(5, OUTPUT);    // e
 
-  lcd.begin(16,2);
+  lcd.begin(84, 48);
   lcd.print("Starting....");
 
+#ifdef DEBUG  
   Serial.begin(9600);
   Serial.println("Starting....");
+#endif
+  
   delay(500);
   
   model_defaults();
@@ -336,6 +219,8 @@ void setup(){
   set_timer( seplength );
   Timer1.initialize(framelength);
   Timer1.attachInterrupt(ISR_timer);  
+
+  lcd.clear();
   
 }
 
@@ -757,7 +642,7 @@ void process_inputs(void )
     // Test to see if dualrate-switch #1 applies to channel...
     if ( ( current_input == ( model.dr[2]-1) ) || ( current_input == ( model.dr[3]-1) ) )
     {
-            if ( !keys[KEY_DR1] )
+            if ( !keys[KEY_DR2] )
                     dr_val = ((float)model.dr[6])/100.0; 
             else
                     dr_val = ((float)model.dr[7])/100.0;
@@ -859,7 +744,10 @@ void dr_inputselect( int no, int in )
        lcd.setCursor(0 , 0);
        lcd.print("D/R switch ");
        lcd.print( no + 1 );
-       lcd.print("    ");
+       //lcd.print("    ");
+       
+       lcd.setCursor(0 , 1);
+       lcd.print("              ");
        lcd.setCursor(0 , 1);
        lcd.print("Input ");
        lcd.print(in+1);
@@ -895,7 +783,10 @@ void dr_value()
        lcd.setCursor(0 , 0);
        lcd.print("D/R switch ");
        lcd.print( menu_substate - 3 );
-       lcd.print("    ");
+
+
+       lcd.setCursor(0 , 1);
+       lcd.print("              ");
        lcd.setCursor(0 , 1);
        lcd.print( state ? "HI" : "LO" );
        lcd.print(" Value :");
@@ -919,6 +810,9 @@ void ui_handler()
   int col;
   scan_keys();
 
+  if ( check_key( KEY_UP) || check_key(KEY_DOWN))
+       lcd.clear();
+
   if ( displaystate != MENU )
   {
        menu_substate = 0;
@@ -944,45 +838,74 @@ void ui_handler()
       return; 
     }
   }
-
+       
   digitalWrite(13, digitalRead(13) ^ 1 );
 
   switch ( displaystate )
   {
     case VALUES:
-      int current_input;
+         int current_input;
+
+
+         row = 0;
+         col = 0;
+         
+         lcd.setCursor(col, row);
+         lcd.print("            ");
+       
+         lcd.setCursor(col, row);
+         lcd.print("S1:");
+         lcd.print( keys[KEY_DR1] ? "On " : "Off" );
+         lcd.print(" S2:");
+         lcd.print( keys[KEY_DR2] ? "On " : "Off" );
+
+         row = 2;
+         col = 0;
+         
       for (current_input=0; current_input<MAX_INPUTS; current_input++) {
-        // In channel value display, do a simple calc
-        // of the LCD row & column location. With 8 channels
-        // we can fit eight channels as percentage values on
-        // a simple 16x2 display...
-        if ( current_input < 4 )
-        {
-          col = current_input * 4; 
-          row = 0;
-        } 
-        else 
-        {
-          col = (current_input-4) * 4;      
-          row = 1;
-        }
+               if (row == 6)
+               {
+                       row = 2;
+                       col = 40;
+               }
+
         // Overwriting the needed positions with
         // blanks cause less display-flicker than
         // actually clearing the display...
         lcd.setCursor(col, row);
-        lcd.print("    ");
+        lcd.print("      ");
+
         lcd.setCursor(col, row);
+               
+               char mod_indicator = NULL;
+               
+               if (( keys[KEY_DR1] ) && (( model.dr[0] == current_input+1) || ( model.dr[1] == current_input+1)))
+                       mod_indicator = '/';
+
+               if (( keys[KEY_DR2] ) && (( model.dr[2] == current_input+1) || ( model.dr[3] == current_input+1)))
+                       if (mod_indicator) mod_indicator = '|';
+                       else mod_indicator = '\\';
+               
+               if ( mod_indicator) lcd.print(mod_indicator);
+               else lcd.print(" ");
+               
+               lcd.print( current_input+1);
+               lcd.print(":");
         // Display uses percents, while PPM uses ratio....
                // New format on stick values
                lcd.print( (int)model.stick[current_input] );
+
+               row++;
       }
       break;
 
 
     case BATTERY:    
-      lcd.clear();
+      lcd.setCursor(0 , 0);
       lcd.print("Battery level: ");
       lcd.setCursor(0 , 1);
+      lcd.print( "            ");
+      lcd.setCursor(0 , 1);
       lcd.print( (float)battery_val/10);
       lcd.print("V");
       if ( battery_val < BATTERY_LOW ) lcd.print(" - WARNING");
@@ -997,10 +920,12 @@ void ui_handler()
                int minutes;
                int seconds;
                
-               lcd.clear();
+        lcd.setCursor(0 , 0);
                lcd.print("Timer: ");
                lcd.print( clock_timer.running ? "Running" : "Stopped" );
                lcd.setCursor(5 , 1);
+               lcd.print("         ");
+               lcd.setCursor(5 , 1);
                if ( clock_timer.running )
                {
                        clock_timer.value = millis() - (clock_timer.start + clock_timer.init);
@@ -1045,7 +970,7 @@ void ui_handler()
 
                
        case CURMODEL:    
-      lcd.clear();
+      lcd.setCursor(0 , 0);
       lcd.print("Model #: ");
          lcd.print( (int)current_model );
       lcd.setCursor(0 , 1);
@@ -1055,19 +980,25 @@ void ui_handler()
 
          
     case MENU:
-      lcd.clear();
+      lcd.setCursor(0 , 0);
       switch ( menu_mainstate )
       {
         case TOP:
+          lcd.setCursor(0 , 0);
           lcd.print("In MENU mode!");
           lcd.setCursor(0 , 1);
-          lcd.print("Esc UP. Scrl DN.");
+          lcd.print("UP to quit.");
+          lcd.setCursor(0 , 2);
+                 lcd.print("DOWN to scroll");
+
           menu_substate = 0;
           if ( check_key(KEY_UP) ) { 
             displaystate = VALUES; 
+            lcd.clear();
             return; 
           }
           else if ( check_key(KEY_DOWN) ) { 
+                       lcd.clear();
             menu_mainstate = INVERTS; 
             return; 
           }
@@ -1085,10 +1016,12 @@ void ui_handler()
 
           if ( check_key(KEY_UP) ) { 
             menu_mainstate = TOP; 
+                       lcd.clear();
             return; 
           }
           else if ( check_key(KEY_DOWN) ) { 
             menu_mainstate = DUALRATES; 
+                       lcd.clear();
             return; 
           }
 
@@ -1112,10 +1045,12 @@ void ui_handler()
                
           if ( check_key(KEY_UP) ) { 
             menu_mainstate = INVERTS; 
+                       lcd.clear();
             return; 
           }          
           if ( check_key(KEY_DOWN) ) {
             menu_mainstate = EXPOS;
+                       lcd.clear();
             return;
           }
           if ( check_key(KEY_RIGHT) ) { 
@@ -1166,16 +1101,19 @@ void ui_handler()
                  // on the time-horizon :P
           if ( check_key(KEY_UP ) ) { 
             menu_mainstate = DUALRATES; 
+                       lcd.clear();
             return; 
           }          
 #ifdef DEBUG          
           if ( check_key(KEY_DOWN ) ) {
             menu_mainstate = DEBUG_DUMP;
+                       lcd.clear();
             return;
           }
 #else
           if ( check_key(KEY_DOWN ) ) {
             menu_mainstate = TOP;
+                       lcd.clear();
             return;
           }
 
@@ -1192,9 +1130,11 @@ void ui_handler()
           if ( check_key(KEY_UP ) ) { 
             // FIXME: Remember to update the "Scroll up" state!
             menu_mainstate = EXPOS; 
+                       lcd.clear();
             return; 
           } else if ( check_key(KEY_DOWN ) ) {
             menu_mainstate = SAVE;
+                       lcd.clear();
             return;
           }
           break;
@@ -1216,84 +1156,6 @@ void ui_handler()
   return;
 }
 
-// ----------- LCD related functions ---------------
-
-void LCDgotoXY(int x, int y) {
-  LCDWrite(0, 0x80 | x);  // Column.
-  LCDWrite(0, 0x40 | y);  // Row.  ?
-}
-
-//This takes a large array of bits and sends them to the LCD
-void LCDBitmap(char my_array[]){
-  for (int index = 0 ; index < (LCD_X * LCD_Y / 8) ; index++)
-    LCDWrite(LCD_DATA, my_array[index]);
-}
-
-//This function takes in a character, looks it up in the font table/array
-//And writes it to the screen
-//Each character is 8 bits tall and 5 bits wide. We pad one blank column of
-//pixels on each side of the character for readability.
-void LCDCharacter(char character) {
-  LCDWrite(LCD_DATA, 0x00); //Blank vertical line padding
-
-  for (int index = 0 ; index < 5 ; index++)
-    LCDWrite(LCD_DATA, ASCII[character - 0x20][index]);
-    //0x20 is the ASCII character for Space (' '). The font table starts with this character
-
-  LCDWrite(LCD_DATA, 0x00); //Blank vertical line padding
-}
-
-//Given a string of characters, one by one is passed to the LCD
-void LCDString(char *characters) {
-  while (*characters)
-    LCDCharacter(*characters++);
-}
-
-//Clears the LCD by writing zeros to the entire screen
-void LCDClear(void) {
-  for (int index = 0 ; index < (LCD_X * LCD_Y / 8) ; index++)
-    LCDWrite(LCD_DATA, 0x00);
-    
-  LCDgotoXY(0, 0); //After we clear the display, return to the home position
-}
-
-//This sends the magical commands to the PCD8544
-void LCDInit(void) {
-
-  //Configure control pins
-  pinMode(PIN_SCE, OUTPUT);
-  pinMode(PIN_RESET, OUTPUT);
-  pinMode(PIN_DC, OUTPUT);
-  pinMode(PIN_SDIN, OUTPUT);
-  pinMode(PIN_SCLK, OUTPUT);
-
-  //Reset the LCD to a known state
-  digitalWrite(PIN_RESET, LOW);
-  digitalWrite(PIN_RESET, HIGH);
-
-  LCDWrite(LCD_COMMAND, 0x21); //Tell LCD that extended commands follow
-  LCDWrite(LCD_COMMAND, 0xB0); //Set LCD Vop (Contrast): Try 0xB1(good @ 3.3V) or 0xBF if your display is too dark
-  LCDWrite(LCD_COMMAND, 0x04); //Set Temp coefficent
-  LCDWrite(LCD_COMMAND, 0x14); //LCD bias mode 1:48: Try 0x13 or 0x14
-
-  LCDWrite(LCD_COMMAND, 0x20); //We must send 0x20 before modifying the display control mode
-  LCDWrite(LCD_COMMAND, 0x0C); //Set display control, normal mode. 0x0D for inverse
-}
-
-//There are two memory banks in the LCD, data/RAM and commands. This 
-//function sets the DC pin high or low depending, and then sends
-//the data byte
-void LCDWrite(byte data_or_command, byte data) {
-  digitalWrite(PIN_DC, data_or_command); //Tell the LCD that we are writing either to data or a command
-
-  //Send the data
-  digitalWrite(PIN_SCE, LOW);
-  shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data);
-  digitalWrite(PIN_SCE, HIGH);
-}
-
-
-
 #ifdef DEBUG
 /* The following code is taken from the 
    Arduino FAT16 Library by William Greiman