Ce site contient essentiellement des notes de travail. Le contenu est en constante évolution, et loin d'être achevé. (+ d'infos)
La plupart des documentations informatiques sont orientées Debian / Ubuntu.

Electronique/Hardware/EagleTree/PowerPanel

De Ordinoscope.net
Sauter à la navigation Sauter à la recherche

Introduction

EagleTree PowerPanel

Trouvé cet exemple intéressant pour utiliser le LCD Display d'EagleTree avec un Arduino.

Code

//**************************
// Arduino support for Eagle Tree Power Panel
// The Power Panel is a small, light weight, 2x16, transflective (readable in sunlight) LCD that interfaces via i2c bus (two wire).
// http://www.eagletreesystems.com/MicroPower/9.htm
// It is sold for use with an Eagle Tree system.  This code allows an Arduino to drive the panel directly. 
//**************************
// Danal.Estes(at)gmail.com
//**************************
// White wire  to Ground
// Red wire    to +5V VCC
// Yellow wire to A4
// Brown wire  to A5
//**************************

//*******************************************************************************************************************************************************************
// Start of configurable parameters

#define INTERNAL_I2C_PULLUPS           // Comment this line if external i2c pullup resistors are present in your hardware implementation. 

// End of configurable parameters
//*******************************************************************************************************************************************************************

// *********************
// This version provides its own i2c primitives. There is another version that uses the Arduino provided Wire library at the cost of ~+966 bytes. 
// *********************
  #define I2C_SPEED 100000L            // 100kHz normal mode, this value must be used for a genuine WMP
// Two wire bus definitions for Arduino Uno, Pro, MiniPro, etc. 
  #define I2C_PULLUPS_ENABLE         PORTC |= 1<<4; PORTC |= 1<<5;       // PIN A4&A5 (SDA&SCL)
  #define I2C_PULLUPS_DISABLE        PORTC &= ~(1<<4); PORTC &= ~(1<<5);
//  Arduino Mega2560 uses different pins, therefore different registers.  
//  #define I2C_PULLUPS_ENABLE         PORTD |= 1<<0; PORTD |= 1<<1;       // PIN 20&21 (SDA&SCL)
//  #define I2C_PULLUPS_DISABLE        PORTD &= ~(1<<0); PORTD &= ~(1<<1);
  #define TW_STATUS_MASK  (1<<TWS7) | (1<<TWS6) | (1<<TWS5) | (1<<TWS4) | (1<<TWS3)    // Mask prescaler bits : only 5 bits of TWSR defines the status of each I2C request
  #define TW_STATUS       (TWSR & TW_STATUS_MASK)
  
  void i2c_init(void) {
    #if defined(INTERNAL_I2C_PULLUPS)
      I2C_PULLUPS_ENABLE
    #else
      I2C_PULLUPS_DISABLE
    #endif
    TWSR = 0;        // no prescaler => prescaler = 1
    TWBR = ((16000000L / I2C_SPEED) - 16) / 2; // change the I2C clock rate
    TWCR = 1<<TWEN;  // enable twi module, no interrupt
  }
  void i2c_rep_start(uint8_t address) {
    TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN)  ;//| (1<<TWSTO); // send REAPEAT START condition
    waitTransmissionI2C(); // wait until transmission completed
    checkStatusI2C(); // check value of TWI Status Register
    TWDR = address; // send device address
    TWCR = (1<<TWINT) | (1<<TWEN);
    waitTransmissionI2C(); // wait until transmission completed
    checkStatusI2C(); // check value of TWI Status Register
  }
  void i2c_write(uint8_t data ) {	
    TWDR = data; // send data to the previously addressed device
    TWCR = (1<<TWINT) | (1<<TWEN);
    waitTransmissionI2C(); // wait until transmission completed
    checkStatusI2C(); // check value of TWI Status Register
  }
  uint8_t i2c_readAck() {
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
    waitTransmissionI2C();
    return TWDR;
  }
  uint8_t i2c_readNak(void) {
    TWCR = (1<<TWINT) | (1<<TWEN);
    waitTransmissionI2C();
    return TWDR;
  }
  void waitTransmissionI2C() {
    uint8_t count = 255;
    while (count-->0 && !(TWCR & (1<<TWINT)) );
    if (count<2) { //we are in a blocking state => we don't insist
      TWCR = 0;  //and we force a reset on TWINT register
    }
  }
  void checkStatusI2C() {
    uint8_t tstat = TW_STATUS;
    if ( tstat  == 0xF8) { //TW_NO_INFO : this I2C error status indicates a wrong I2C communication.
      exit(1);  //Fatal
    } 
  }
//*******************************************************************************************************************************************************************

// *********************
// i2c Eagle Tree Power Panel primitives
// *********************
  void i2c_ETPP_init () {
    i2c_rep_start(0x76+0);      // ETPP i2c address: 0x3B in 7 bit form. Shift left one bit and concatenate i2c write command bit of zero = 0x76 in 8 bit form.
    i2c_write(0x00);            // ETPP command register
    i2c_write(0x24);            // Function Set 001D0MSL D : data length for parallel interface only; M: 0 = 1x32 , 1 = 2x16; S: 0 = 1:18 multiplex drive mode, 1×32 or 2×16 character display, 1 = 1:9 multiplex drive mode, 1×16 character display; H: 0 = basic instruction set plus standard instruction set, 1 = basic instruction set plus extended instruction set
    i2c_write(0x0C);            // Display on   00001DCB D : 0 = Display Off, 1 = Display On; C : 0 = Underline Cursor Off, 1 = Underline Cursor On; B : 0 = Blinking Cursor Off, 1 = Blinking Cursor On
    i2c_write(0x06);            // Cursor Move  000001IS I : 0 = DDRAM or CGRAM address decrements by 1, cursor moves to the left, 1 = DDRAM or CGRAM address increments by 1, cursor moves to the right; S : 0 = display does not shift,  1 = display does shifts
    lcdClear();         
  }
  void i2c_ETPP_send_cmd (byte c) {
    i2c_rep_start(0x76+0);      // I2C write direction
    i2c_write(0x00);            // ETPP command register
    i2c_write(c);
  }
  void i2c_ETPP_send_char (char c) {
    if (c > 0x0f) c |=  0x80;   // ETPP uses character set "R", which has A->z mapped same as ascii + high bit; don't mess with custom chars. 
    i2c_rep_start(0x76+0);      // I2C write direction
    i2c_write(0x40);            // ETPP data register
    i2c_write(c);
  }
  void i2c_ETPP_send_string (const char *s) {
    i2c_rep_start(0x76+0);      // I2C write direction
    i2c_write(0x40);            // ETPP data register
    while (*s) {byte c = *s++; if (c > 0x0f) c |=  0x80; i2c_write(c);}
  }
  void i2c_ETPP_set_cursor (byte addr) {  
    i2c_ETPP_send_cmd(0x80 | addr);    // High bit is "Set DDRAM" command, remaing bits are addr.  
  }
  void i2c_ETPP_set_cursor (byte col, byte row) {  
    row = min(row,1);
    col = min(col,15);  
    byte addr = col + row * 0x40;      // Why 0x40? RAM in this controller has many more bytes than are displayed.  In particular, the start of the second line (line 1 char 0) is 0x40 in DDRAM. The bytes between 0x0F (last char of line 1) and 0x40 are not displayable (unless the display is placed in marquee scroll mode)
    i2c_ETPP_set_cursor(addr);          
  }
  void i2c_ETPP_create_char (byte idx, uint8_t* array) {
    i2c_ETPP_send_cmd(0x80);                   // CGRAM and DDRAM share an address register, but you can't set certain bits with the CGRAM address command.   Use DDRAM address command to be sure high order address bits are zero. 
    i2c_ETPP_send_cmd(0x40 | byte(idx * 8));   // Set CGRAM address 
    i2c_rep_start(0x76+0);                     // I2C write direction
    i2c_write(0x40);                           // ETPP data register
    for (byte i = 0 ; i<8 ; i++) {i2c_write(*array); array++;}
  }
//*******************************************************************************************************************************************************************

// *********************
// Functions that mimic LiquidCrystal library functions and work with ETPP
// *********************
  void lcdClear() {
    i2c_ETPP_send_cmd(0x01);                              // Clear display command, which does NOT clear an Eagle Tree because character set "R" has a '>' at 0x20
    for (byte i = 0; i<80; i++) i2c_ETPP_send_char(' ');  // Blanks for all 80 bytes of RAM in the controller, not just the 2x16 display
  }
  void lcdBlink()                                                      {
    i2c_ETPP_send_cmd(0x0D);            // Display on   00001DCB D : 0 = Display Off, 1 = Display On; C : 0 = Underline Cursor Off, 1 = Underline Cursor On; B : 0 = Blinking Cursor Off, 1 = Blinking Cursor On
  }
  void lcdNoBlink()                                                      {
    i2c_ETPP_send_cmd(0x0C);            // Display on   00001DCB D : 0 = Display Off, 1 = Display On; C : 0 = Underline Cursor Off, 1 = Underline Cursor On; B : 0 = Blinking Cursor Off, 1 = Blinking Cursor On
  }
  void lcdCursor()                                                      {
    i2c_ETPP_send_cmd(0x0E);            // Display on   00001DCB D : 0 = Display Off, 1 = Display On; C : 0 = Underline Cursor Off, 1 = Underline Cursor On; B : 0 = Blinking Cursor Off, 1 = Blinking Cursor On
  }
  void lcdNoCursor()                                                      {
    i2c_ETPP_send_cmd(0x0C);            // Display on   00001DCB D : 0 = Display Off, 1 = Display On; C : 0 = Underline Cursor Off, 1 = Underline Cursor On; B : 0 = Blinking Cursor Off, 1 = Blinking Cursor On
  }
  void lcdCreateChar(int8_t idx, uint8_t* array)                       {i2c_ETPP_create_char(idx, array);}
  void lcdSetCursor(uint8_t pos)                                       {i2c_ETPP_set_cursor(pos % 16, pos / 16);}
  void lcdWrite(int8_t digit)                                          {i2c_ETPP_send_char(digit);}
  void lcdWrite(uint8_t pos, int8_t digit)                             {lcdSetCursor(pos); lcdWrite(digit);}
  void lcdPrint                  (char const      msg[])               {i2c_ETPP_send_string(msg);}
  void lcdPrint     (uint8_t pos, char const      msg[])               {lcdSetCursor(pos); lcdPrint(msg);}

//*******************************************************************************************************************************************************************
// The functions above are for use in your sketches.
// The data and functions below are examples of how to use them.
//*******************************************************************************************************************************************************************

  int count;
  char buf[17];
  char line1[17];

  static byte lessthan[8] = { 0x03, 0x07, 0x0E, 0x1C, 0x0E, 0x07, 0x03, 0x00, };    // 5x8 bit pattern for 5x7 custom character (and 8th line for cursor, not used in this example)
  static byte grththan[8] = { 0x18, 0x1C, 0x0E, 0x07, 0x0E, 0x1C, 0x18, 0x00};      // 5x8 bit pattern for 5x7 custom character (and 8th line for cursor, not used in this example)

  char* strings[]={"0              \002",               // Array of strings for line 2 of demonstration code. These include the custom characters above. 
                   "\0011             \002",  
                   "\001 2            \002",  
                   "\001  3           \002",  
                   "\001   4          \002",  
                   "\001    5         \002",  
                   "\001     6        \002",  
                   "\001      7       \002",  
                   "\001       8      \002",  
                   "\001        9     \002",  
                   "\001         A    \002",  
                   "\001          B   \002",  
                   "\001           C  \002",  
                   "\001            D \002",  
                   "\001             E\002",  
                   "\001              F",  
                  };
//*******************************************************************************************************************************************************************
  
void setup() {
  pinMode(13, OUTPUT);   // For later blinking of the LED
  
  i2c_init();            // Join the i2c bus as a host
  i2c_ETPP_init();       // Initalize the Eagle Tree Power Panel
  
  //Print a test pattern
  lcdPrint(0,"1234567891123456");       // Position zero (line 0, character 0) = start of line 1
  lcdPrint(16,"ABCDEFGHIJKLMNOP");      // Position 16   (line 1, character 0) = start of line 2
  delay(1000);
  
  // Print a personal message
  lcdClear();                           // Write blanks to all positions (if not, previous message would remain anywhere a character is not written)   
  lcdPrint("Danal's ETPP");             // Position not specified              = start of line 1
  lcdPrint(16,"support code");          // Position 16   (line 1, character 0) = start of line 2
  delay(1000);

  // Create some custom characters; up to 16 custom chars allowed; avoid using custom char 0x00 if you send strings
  lcdCreateChar(1,lessthan);            // Create a custom character in ETPP LCD's CGRAM.  Invoke later with 0x01 in data stream 
  lcdCreateChar(2,grththan);            // Create a custom character in ETPP LCD's CGRAM.  Invoke later with 0x02 in data stream 
}

//*******************************************************************************************************************************************************************
// End setup
//*******************************************************************************************************************************************************************

void loop() {
  
  // Blink the LED, just for fun
  digitalWrite(13, HIGH);   // set the LED on
  delay(25);           
  digitalWrite(13, LOW);    // set the LED off
  delay(250);
  
  // One approach to constructing a line: Build an in-memory buffer, then send it. 
  strcpy(line1,"                ");                                          // Start with a blank buffer for line 1 of the display
  itoa(count,buf,DEC);                                                       // Convert our current count from an integer to displayable characters
  for (byte i=0; ((i<16) && (buf[i] != 0)); i++) {line1[i+9] = buf[i];}      // Place it in the line1 buffer starting at position 9.  Positions 9 through 16 is enough room for the largest possible display of a signed integer (namely -32768).
  itoa(word(millis() & 0x7FFF),buf,DEC);                                     // Convert the current timestamp from an integer to displayable characters
  for (byte i=0; ((i<16) && (buf[i] != 0)); i++) {line1[i] = buf[i];}        // Place it in the line1 buffer starting at position 0
  lcdPrint(0,line1);                                                         // Print line1 on the LCD, starting at position 0 (line 0, character 0)

  // Another approach: Print directly to the LCD in a specific position, adding to the display that is already there.
  lcdSetCursor(7);                                                           // Set the cursor two characters before the 'count' printed in the code above
  lcdPrint("C=");                                                            // Add the label by writing to position 7 and 8 on the LCD

  // And another approach: Print strings stored elsewhere in our sketch
  lcdPrint(16,strings[abs(count % 16)]);                                     // Print a selected line from our demo array on the LCD at position 16 (line 1, character 0).  Note these lines contain invocations of the custom characters loaded during setup.

  count++;                                                                   // Increment the counter that is displayed.  Note it is signed, so it will cycle between -32768 and 32768 over and over. 
}

//*******************************************************************************************************************************************************************
// End loop
//*******************************************************************************************************************************************************************

// Example of how to print a string in hex at the current cursor position on the LCD.  Quite useful for debugging:
//  char str[];     // some string to print in hex
//  char buf[3];
//  for (byte i=0; (i<7 && str[i] != 0x00); i++) {                                // Limit the input string to 8 bytes (16 hex chars output, the width of the LCD)
//    itoa(byte(str[i]),buf,HEX);                                                 // Convert a single input byte to hex
//    if (buf[1] == 0) {buf[1] = buf[0]; buf[0] = '0'; buf[2] = 0;}               // If necessary, add a leading zero
//    i2c_ETPP_send_string(buf);                                                  // Print it on the LCD, using ETPP primitive function
//  }


/*
  Copyright (c) 2006 Danal Estes.  All right reserved.

  This sketch is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 3 of the License, or (at your option) any later version.

  This sketch is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this code; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  or see http://www.gnu.org/licenses/gpl.html 
*/

Références