Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
I2C 4x20 display with OTG and Micro
22-04-2012, 12:58 AM, (This post was last modified: 22-04-2012, 01:10 AM by KiloOne.)
#11
RE: I2C 4x20 display with OTG and Micro
So I spent the day trying to solve this.

I have pared the code down so that there are no include files whatsoever and still can not display the firmware version number on the display.

I am even sending some smoke signals on the green LED to make sure things are not timing out.

regis I have looked at the files you suggested but do not really see anything that helps right now.

Here is the includeless code:
Code:
    u8 wv = 0;
    int g_i2caddress = 0x50 >> 1;             // NHD documents address in 8-bit but arduino uses 7
    int g_cmdDelay = 10;
    #define I2C_TIMEOUT    4000    
    #define I2C1                    1

u8 writechar(u8 module, u8 value){
    int i = 0;
    I2C1TRN = value;                                     //7 bit address byte should be shifted left 0x77<<1
    while (I2C1STATbits.TBF == 1);                //wait for buffer empty
    while (I2C1STATbits.ACKSTAT == 1)
          if (++i >= I2C_TIMEOUT) {
             return false;
          }
          ;                                                    // wait until Slave sends ACK
    while (IFS0bits.I2C1MIF== 0)
          if (++i >= I2C_TIMEOUT) {
             return false;
          }                                                    // wait until buffer clear
         ;
    IFS0bits.I2C1MIF = 0;
        return true;
}

void command(uint8_t value) {
    start(I2C1);
    wv = writechar(I2C1,g_i2caddress);
    if (wv = TRUE) {
        digitalWrite(13,LOW);
        delay(200);
        digitalWrite(13,HIGH);
        delay(200);
        digitalWrite(13,LOW);
        delay(200);
        }
    wv = writechar(I2C1,0xFE);
    if (wv = TRUE) {
        digitalWrite(13,LOW);
        delay(200);
        digitalWrite(13,HIGH);
        delay(200);
        digitalWrite(13,LOW);
        delay(200);
        }
    wv = writechar(I2C1,value);
    if (wv = TRUE) {
        digitalWrite(13,LOW);
        delay(200);
        digitalWrite(13,HIGH);
        delay(200);
        digitalWrite(13,LOW);
        delay(200);
        }
    stop(I2C1);                            
      delay(g_cmdDelay);
}

void start(u8 module){
    I2C1CONbits.SEN = 1;
    while (I2C1CONbits.SEN == 1);                    // wait until start clear
    while (IFS0bits.I2C1MIF== 0);
    IFS0bits.I2C1MIF = 0;
}

void stop(u8 module){
    I2C1CONbits.PEN = 1;
    while (I2C1CONbits.PEN == 1);                    // wait until stop clear                                               
    while (IFS0bits.I2C1MIF== 0);
    IFS0bits.I2C1MIF = 0;
}


void setup() {
    u32 pbclk = GetPeripheralClock();
    I2C1CONbits.DISSLW = 1;                        // 1 = Slew rate control disabled for Standard Speed mode (100 kHz); also disabled for 1 MHz mode
    I2C1BRG = (pbclk / (2*100*1000))-2;        // 100khz
    I2C1CONSET = (1 << 15);                        // Set bit 15 Enables the I2C module and configures the SDA and SCL pins as serial port pins
    
    pinMode(13,OUTPUT);
}

void loop()  {
    command(0x70);                                    //0x70 tells display to Display firmware version number
    digitalWrite(13,HIGH);
    delay(2500);
    digitalWrite(13,LOW);
    delay(500);
}

Any more suggestions?

Thanks,
Dale
PIC32-Pinguino-OTG Rev C and PIC32-PINGUINO-MICRO rev.B
Win XP SP3
r381 x.3 Big Grin
AND spi.c {} error fixed
AND sdmmc.c pin error fixed
AND diskio.c fixed, MICRO can't use the RTCC
AND analog.c fixed for MICRO
Reply
22-04-2012, 02:02 AM, (This post was last modified: 22-04-2012, 02:03 AM by KiloOne.)
#12
RE: I2C 4x20 display with OTG and Micro
So I broke down and looked at the SDA and SCL lines with a scope.

No 100kHz activity at all on either line.

The SDA (A4) line stays high all the time.

The SCL (A5) line is high only during the 3 seconds that the command() calls are inactive.

So, there really is not much of an attempt by the PIC to communicate.

Help!
Dale
PIC32-Pinguino-OTG Rev C and PIC32-PINGUINO-MICRO rev.B
Win XP SP3
r381 x.3 Big Grin
AND spi.c {} error fixed
AND sdmmc.c pin error fixed
AND diskio.c fixed, MICRO can't use the RTCC
AND analog.c fixed for MICRO
Reply
22-04-2012, 05:08 AM,
#13
RE: I2C 4x20 display with OTG and Micro
Get one of these ... http://www.saleae.com/logic
It will help you see what is happening on the I2C bus. It decodes the bytes, start, stop, ack, etc.

Each I2C device has a different command set. So you need to know that you are sending the correct sequences.
Some devices require that you send one byte at a time. Others can accept many bytes in sequence.

If you send the wrong address byte or command byte, the receiving device will not reply with an ACK.
For 7 bit addressed devices, the address byte is the device address shifted one bit to the left. The last bit signals a read or write.

In my experience the logic analyzer is the quickest way to verify I2C communication.
Reply
22-04-2012, 11:10 AM,
#14
RE: I2C 4x20 display with OTG and Micro
I can't believe that I have to go trough so much trouble to get this display to work.

I have been looking at this logic analyzer for a while and just ordered one, I like the software ui and there is a '30 free protocols' offer right now. I also have amazon prime and can have it here Tuesday for $3.99 shipping: http://www.amazon.com/Zeroplus-LAP-C-160...01_03_t_lh

That aside, after playing with the trigger and timescale on my scope some more, I can see some signal pulses once in a while so they may be there but I will have to wait until my logic analyzer comes to see what the signals really are.

All the I2C commands and sequences were fine under Arduino wire control, I guess with the analyzer we'll see exactly what needs to change in pic land.

Thanks,
Dale
PIC32-Pinguino-OTG Rev C and PIC32-PINGUINO-MICRO rev.B
Win XP SP3
r381 x.3 Big Grin
AND spi.c {} error fixed
AND sdmmc.c pin error fixed
AND diskio.c fixed, MICRO can't use the RTCC
AND analog.c fixed for MICRO
Reply
22-04-2012, 03:10 PM,
#15
RE: I2C 4x20 display with OTG and Micro
Just a thought, but the PIC32 is vastly faster than the Arduino so maybe you need delays. Your device data sheet should tell you (though in my experience they do it very badly indeed, especially if your background is software).

John
Reply
22-04-2012, 08:08 PM,
#16
RE: I2C 4x20 display with OTG and Micro
RLmonitor gets the prize!!!

If only I knew C as well as I know VB, the answer was right there staring at me in the 2nd line of code I have been posting since post #10.

But I have learned a LOT in this exercise and although I would not want to repeat it, I have to say it was worthwhile and I will have a new toy to play with on Tuesday.

Not sure how my green led smoke signals I tried to put in the code of post #11 failed to tell me that ACK was not received back then.

I actually realized that the display was not sending an ACK after it received the address by looking at the scope images after I figured out how to reliably trigger on the bits.

Then I saw it, the rem in the 2nd line of code says "NHD documents address in 8-bit but arduino uses 7" and that was the aha moment, the OTG pic uses 8-bit (dah).

It was fun (I guess).

Here is the pared code that works:
Code:
int wr = 0;

u8 writechar(u8 module, u8 value){
    int i = 0;
    I2C1TRN = value;                                     //7 bit address byte should be shifted left 0x77<<1
    while (I2C1STATbits.TBF == 1);                //wait for buffer empty
    while (I2C1STATbits.ACKSTAT == 1)
          if (++i >= 4000) {
             return false;
          }
          ;                                                    // wait until Slave sends ACK
    i = 0;                                                //dk reset counter
    while (IFS0bits.I2C1MIF== 0);
          if (++i >= 4000) {
             return false;
          }                                                    // wait until buffer clear
         ;
    IFS0bits.I2C1MIF = 0;
        return true;
}

void setup() {
    u32 pbclk = GetPeripheralClock();
    I2C1CONbits.DISSLW = 1;                        // 1 = Slew rate control disabled for Standard Speed mode (100 kHz); also disabled for 1 MHz mode
    I2C1BRG = (pbclk / (2*100*1000))-2;        // 100khz
    I2C1CONSET = (1 << 15);                        // Set bit 15 Enables the I2C module and configures the SDA and SCL pins as serial port pins
}

void loop()  {
    start(1);                                            // use I2C1 (A4 and A5 on OTG)
    wr = writechar(1,0x50);                            // 4x20 display address  (8 bits for OTG and MICRO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)
    wr = writechar(1,0xFE);                            //0xFE then 0x70 tells display to Display firmware version number
    wr = writechar(1,0x70);
    stop(1);                            
      delayMicroseconds(200);
}

void start(u8 module){
    I2C1CONbits.SEN = 1;
    while (I2C1CONbits.SEN == 1);                    // wait until start clear
    while (IFS0bits.I2C1MIF== 0);
    IFS0bits.I2C1MIF = 0;
}

void stop(u8 module){
    I2C1CONbits.PEN = 1;
    while (I2C1CONbits.PEN == 1);                    // wait until stop clear                                               
    while (IFS0bits.I2C1MIF== 0);
    IFS0bits.I2C1MIF = 0;
}

Also, can someone tell me if the line I have added in the i2c.c writechar function (the 2nd i = 0 line) adds anything? I think this counter needs this reset before it is used again.

And, I just have to show a couple pictures, one of the displayed version number and a scope image of the serial and clock bits that did this. Yeah.

Thanks everyone, and now on to having the pic talk to my SPI devices.
Dale

   

   
PIC32-Pinguino-OTG Rev C and PIC32-PINGUINO-MICRO rev.B
Win XP SP3
r381 x.3 Big Grin
AND spi.c {} error fixed
AND sdmmc.c pin error fixed
AND diskio.c fixed, MICRO can't use the RTCC
AND analog.c fixed for MICRO
Reply
22-04-2012, 09:49 PM, (This post was last modified: 22-04-2012, 09:52 PM by pingotg.)
#17
RE: I2C 4x20 display with OTG and Micro
Well done! I was worrying I'd put you off.

If you mean the i = 0 below:
Code:
while (I2C1STATbits.ACKSTAT == 1)
          if (++i >= 4000) {
             return false;
          }
          ;                                                    // wait until Slave sends ACK
    i = 0;
Yes, looks good to have it.

BTW, the line above it does nothing (an extraneous ";" is usually harmless but best left out), and the above can be shortened to:
// wait until Slave sends ACK
Code:
while (I2C1STATbits.ACKSTAT == 1)
          if (++i >= 4000)
             return false;            // give up: no ACK seen
i = 0;

The short reason is that ";" is a terminator not a separator and "{ ... }" doesn't require anything more.

John
Reply
23-04-2012, 03:08 AM,
#18
RE: I2C 4x20 display with OTG and Micro
Thanks John,

I will try to use less extraneous bits in my code but I only added the i = 0; there, the rest was already in the i2c.c.

And, if you or anyone else does not mind helping again, I am having trouble figuring out how to take my functions/subroutines or whatever they are called in C land out of my main .pde file and into a separate .c file so my .pde isn't so big.

Here is the combined .pde that actually produces "Hello World":
Code:
#include <i2c.c>
#include <printf.c>

#define I2C1      1                        // using I2C #1 here
#define _LCDEXPANDED                    // If defined this turns on advanced functions

u8 g_num_lines = 4;
u8 g_num_col = 20;
int g_i2caddress = 0x50;             // NHD documents address in 8-bit
u8 g_display = 0;
u8 g_cmdDelay = 200;
u8 g_charDelay = 0;

//Prototypes
void    NHDwritef(char);                         
void    NHDprintf(char *fmt, ...);
void    NHDinit();
void    NHDsetDelay(u8,u8);
void    NHDcommand(u8);
u8      NHDwrite(u8);
void    NHDclear();
void    NHDhome();
void    NHDon();
void    NHDoff();
void    NHDcursor_on();
void    NHDcursor_off();
void    NHDblink_on();
void    NHDblink_off();
void    NHDsetCursor(u8, u8);
u8      NHDstatus();
void    NHDload_custom_character(u8, u8*);
void    NHDsetBacklight(u8);
void    NHDsetContrast(u8);

void setup()
{
  I2C_init(I2C1, I2C_MASTER_MODE, I2C_100KHZ);
  NHDinit();
}

void loop()  
{
  NHDsetCursor(0,0);
  NHDprintf("Hello World");
  delay(1000);
  NHDsetCursor(2,15);
  NHDprintf("WOW!");
  delay(1000);
  NHDclear();
  delay(500);
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    dk got NHDprintf working with these 2 functions
// []
// [] Just kept looking at serial.c until I kludged it together
// []  
// [] Don't really know how this works but it does the job for me
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDwritef(char value)                         
{
    I2C_writechar(I2C1,value);                
}

void NHDprintf(char *fmt, ...)
{
      I2C_start(I2C1);                        
    I2C_writechar(I2C1,g_i2caddress);         
    va_list args;
    va_start(args, fmt);
    pprintf(NHDwritef, fmt, args);
    va_end(args);
    I2C_stop(I2C1);                            
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    initiatize lcd
// []
// []    Init the i2c buss
// []   Put the display in some kind of known mode
// []   Put the cursor at 0,0
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]


void NHDinit()
{
    NHDon();
    NHDclear();
    NHDblink_off();
    NHDcursor_off();
    NHDhome();
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    Over ride the default delays used to send commands to the display
// []
// []    The default values are set by the library
// []   this allows the programer to take into account code delays
// []   and speed things up.
// []  
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]


void NHDsetDelay(u8 cmdDelay,u8 charDelay)
{
    g_cmdDelay = cmdDelay;
    g_charDelay = charDelay;
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []   Send a command to the display.
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDcommand(u8 value)
{
      I2C_start(I2C1);                        
    I2C_writechar(I2C1,g_i2caddress);         
    I2C_writechar(I2C1,0xFE);                
    I2C_writechar(I2C1,value);                
    I2C_stop(I2C1);                            
      delayMicroseconds(g_cmdDelay);
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []   Send a command to the display.
// []
// []    This is also used by the print, and println
// []    
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

u8 NHDwrite(u8 value)                         //dk    u8 was size_t but size_t won't complie
{
      I2C_start(I2C1);                        
    I2C_writechar(I2C1,value);                
    I2C_stop(I2C1);                            
      delayMicroseconds(g_charDelay);
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    Clear the display, and put cursor at 0,0
// []
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDclear()
{
    NHDcommand(0x51);
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    Home to custor to 0,0
// []
// []    Do not disturb data on the display
// []
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDhome()
{
    NHDsetCursor(0,0);                    // The command to home the cursor does not work on the version 1.3 of the display
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    Turn on the display
// []
// []    Depending on the display, might just turn backlighting on
// []
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDon()
{
      NHDcommand(0x41);
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    Turn off the display
// []
// []    Depending on the display, might just turn backlighting off
// []
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDoff()
{
      NHDcommand(0x42);
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    Turn on the underline cursor
// []
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDcursor_on()
{
      NHDcommand(0x47);
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    Turn off the underline cursor
// []
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDcursor_off()
{
      NHDcommand(0x48);
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    Turn on the blinking block cursor
// []
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDblink_on()
{
      NHDcommand(0x4B);
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    Turn off the blinking block cursor
// []
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDblink_off()
{
      NHDcommand(0x4C);
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    Position the cursor to position line,column
// []
// []    line is 0 - Max Display lines
// []    column 0 - Max Display Width
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDsetCursor(u8 line_num, u8 x)
{
    u8 base = 0x00;
    if (line_num == 1)
        base = 0x40;
    if (line_num == 2)
        base = 0x14;
    if (line_num == 3)
        base = 0x54;
      I2C_start(I2C1);                        
    I2C_writechar(I2C1,g_i2caddress);         
    I2C_writechar(I2C1,0xFE);                
    I2C_writechar(I2C1,0x45);                
    I2C_writechar(I2C1,base + x);            
    I2C_stop(I2C1);                            
    delayMicroseconds(g_cmdDelay*2);
}

#ifdef _LCDEXPANDED
    // [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
    // []
    // []    Return the status of the display
    // []
    // []    Does nothing on this display
    // []
    // [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]    
    
    u8 NHDstatus()    
    {
        return 0;
    }
    
    // [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
    // []
    // []    Load data for a custom character
    // []
    // []    Char = custom character number 0-7
    // []    Row is array of chars containing bytes 0-7
    // []
    // []
    // [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
    
    void NHDload_custom_character(u8 char_num, u8 *rows)     
    {
          I2C_start(I2C1);                        
        I2C_writechar(I2C1,g_i2caddress);         
        I2C_writechar(I2C1,0xFE);                
        I2C_writechar(I2C1,0x54);                
        I2C_writechar(I2C1,char_num);            
        I2C_writechar(I2C1,rows[0]);    
        I2C_writechar(I2C1,rows[1]);    
        I2C_writechar(I2C1,rows[2]);    
        I2C_writechar(I2C1,rows[3]);    
        I2C_writechar(I2C1,rows[4]);    
        I2C_writechar(I2C1,rows[5]);    
        I2C_writechar(I2C1,rows[6]);    
        I2C_writechar(I2C1,rows[7]);    
        I2C_stop(I2C1);                            
        delayMicroseconds(g_cmdDelay);
    }
    
    void NHDsetBacklight(u8 new_val)     
    {
          I2C_start(I2C1);                        
        I2C_writechar(I2C1,g_i2caddress);         
        I2C_writechar(I2C1,0xFE);                
        I2C_writechar(I2C1,0x53);                
        I2C_writechar(I2C1,new_val);            
        I2C_stop(I2C1);                            
        delayMicroseconds(g_cmdDelay);
    }
    
    void NHDsetContrast(u8 new_val)     
    {
          I2C_start(I2C1);                        
        I2C_writechar(I2C1,g_i2caddress);         
        I2C_writechar(I2C1,0xFE);                
        I2C_writechar(I2C1,0x52);                
        I2C_writechar(I2C1,new_val);            
        I2C_stop(I2C1);                            
        delayMicroseconds(g_cmdDelay);
    }
#endif

And here is my attempt at splitting the routines out, first the shortened .pde file:
Code:
#include <NHD.c>

void setup()
{
  I2C_init(I2C1, I2C_MASTER_MODE, I2C_100KHZ);
  NHDinit();
}

void loop()  
{
  NHDsetCursor(0,0);
  NHDprintf("Hello World");
  delay(1000);
  NHDsetCursor(2,15);
  NHDprintf("WOW!");
  delay(1000);
  NHDclear();
  delay(500);
}

And the attempt at the NHD.c file:
Code:
#include <i2c.c>
#include <printf.c>

#define I2C1      1                        // using I2C #1 here
#define _LCDEXPANDED                    // If defined this turns on advanced functions

u8 g_num_lines = 4;
u8 g_num_col = 20;
int g_i2caddress = 0x50;             // NHD documents address in 8-bit
u8 g_display = 0;
u8 g_cmdDelay = 1;
u8 g_charDelay = 0;

//Prototypes
void    NHDwritef(char);                         
void    NHDprintf(char *fmt, ...);
void    NHDinit();
void    NHDsetDelay(u8,u8);
void    NHDcommand(u8);
u8      NHDwrite(u8);
void    NHDclear();
void    NHDhome();
void    NHDon();
void    NHDoff();
void    NHDcursor_on();
void    NHDcursor_off();
void    NHDblink_on();
void    NHDblink_off();
void    NHDsetCursor(u8, u8);
u8      NHDstatus();
void    NHDload_custom_character(u8, u8*);
void    NHDsetBacklight(u8);
void    NHDsetContrast(u8);

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    dk got NHDprintf working with these 2 functions
// []
// [] Just kept looking at serial.c until I kludged it together
// []  
// [] Don't really know how this works but it does the job for me
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDwritef(char value)                         
{
    I2C_writechar(I2C1,value);                
}

void NHDprintf(char *fmt, ...)
{
      I2C_start(I2C1);                        
    I2C_writechar(I2C1,g_i2caddress);         
    va_list args;
    va_start(args, fmt);
    pprintf(NHDwritef, fmt, args);
    va_end(args);
    I2C_stop(I2C1);                            
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    initiatize lcd
// []
// []    Init the i2c buss
// []   Put the display in some kind of known mode
// []   Put the cursor at 0,0
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]


void NHDinit()
{
    NHDon();
    NHDclear();
    NHDblink_off();
    NHDcursor_off();
    NHDhome();
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    Over ride the default delays used to send commands to the display
// []
// []    The default values are set by the library
// []   this allows the programer to take into account code delays
// []   and speed things up.
// []  
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]


void NHDsetDelay(u8 cmdDelay,u8 charDelay)
{
    g_cmdDelay = cmdDelay;
    g_charDelay = charDelay;
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []   Send a command to the display.
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDcommand(u8 value)
{
      I2C_start(I2C1);                        
    I2C_writechar(I2C1,g_i2caddress);         
    I2C_writechar(I2C1,0xFE);                
    I2C_writechar(I2C1,value);                
    I2C_stop(I2C1);                            
      delayMicroseconds(g_cmdDelay);
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []   Send a command to the display.
// []
// []    This is also used by the print, and println
// []    
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

u8 NHDwrite(u8 value)                         //dk    u8 was size_t but size_t won't complie
{
      I2C_start(I2C1);                        
    I2C_writechar(I2C1,value);                
    I2C_stop(I2C1);                            
      delayMicroseconds(g_charDelay);
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    Clear the display, and put cursor at 0,0
// []
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDclear()
{
    NHDcommand(0x51);
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    Home to custor to 0,0
// []
// []    Do not disturb data on the display
// []
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDhome()
{
    NHDsetCursor(0,0);                    // The command to home the cursor does not work on the version 1.3 of the display
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    Turn on the display
// []
// []    Depending on the display, might just turn backlighting on
// []
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDon()
{
      NHDcommand(0x41);
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    Turn off the display
// []
// []    Depending on the display, might just turn backlighting off
// []
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDoff()
{
      NHDcommand(0x42);
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    Turn on the underline cursor
// []
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDcursor_on()
{
      NHDcommand(0x47);
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    Turn off the underline cursor
// []
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDcursor_off()
{
      NHDcommand(0x48);
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    Turn on the blinking block cursor
// []
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDblink_on()
{
      NHDcommand(0x4B);
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    Turn off the blinking block cursor
// []
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDblink_off()
{
      NHDcommand(0x4C);
}

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []    Position the cursor to position line,column
// []
// []    line is 0 - Max Display lines
// []    column 0 - Max Display Width
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

void NHDsetCursor(u8 line_num, u8 x)
{
    u8 base = 0x00;
    if (line_num == 1)
        base = 0x40;
    if (line_num == 2)
        base = 0x14;
    if (line_num == 3)
        base = 0x54;
      I2C_start(I2C1);                        
    I2C_writechar(I2C1,g_i2caddress);         
    I2C_writechar(I2C1,0xFE);                
    I2C_writechar(I2C1,0x45);                
    I2C_writechar(I2C1,base + x);            
    I2C_stop(I2C1);                            
    delayMicroseconds(g_cmdDelay*2);
}

#ifdef _LCDEXPANDED
    // [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
    // []
    // []    Return the status of the display
    // []
    // []    Does nothing on this display
    // []
    // [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]    
    
    u8 NHDstatus()    
    {
        return 0;
    }
    
    // [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
    // []
    // []    Load data for a custom character
    // []
    // []    Char = custom character number 0-7
    // []    Row is array of chars containing bytes 0-7
    // []
    // []
    // [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
    
    void NHDload_custom_character(u8 char_num, u8 *rows)     
    {
          I2C_start(I2C1);                        
        I2C_writechar(I2C1,g_i2caddress);         
        I2C_writechar(I2C1,0xFE);                
        I2C_writechar(I2C1,0x54);                
        I2C_writechar(I2C1,char_num);            
        I2C_writechar(I2C1,rows[0]);    
        I2C_writechar(I2C1,rows[1]);    
        I2C_writechar(I2C1,rows[2]);    
        I2C_writechar(I2C1,rows[3]);    
        I2C_writechar(I2C1,rows[4]);    
        I2C_writechar(I2C1,rows[5]);    
        I2C_writechar(I2C1,rows[6]);    
        I2C_writechar(I2C1,rows[7]);    
        I2C_stop(I2C1);                            
        delayMicroseconds(g_cmdDelay);
    }
    
    void NHDsetBacklight(u8 new_val)     
    {
          I2C_start(I2C1);                        
        I2C_writechar(I2C1,g_i2caddress);         
        I2C_writechar(I2C1,0xFE);                
        I2C_writechar(I2C1,0x53);                
        I2C_writechar(I2C1,new_val);            
        I2C_stop(I2C1);                            
        delayMicroseconds(g_cmdDelay);
    }
    
    void NHDsetContrast(u8 new_val)     
    {
          I2C_start(I2C1);                        
        I2C_writechar(I2C1,g_i2caddress);         
        I2C_writechar(I2C1,0xFE);                
        I2C_writechar(I2C1,0x52);                
        I2C_writechar(I2C1,new_val);            
        I2C_stop(I2C1);                            
        delayMicroseconds(g_cmdDelay);
    }
#endif

When I compile this small .pde I get no indication why it won't link, here is the compiler output:
Board: PIC32_Pinguino_OTG
Proc: 32MX440F256H
error while linking C:\Pinguino32X.2\Dale\NHD\HELLOWORLD-NHD.o

Been stuck here for a while, what do I need to do?

Thanks,
Dale
PIC32-Pinguino-OTG Rev C and PIC32-PINGUINO-MICRO rev.B
Win XP SP3
r381 x.3 Big Grin
AND spi.c {} error fixed
AND sdmmc.c pin error fixed
AND diskio.c fixed, MICRO can't use the RTCC
AND analog.c fixed for MICRO
Reply
23-04-2012, 08:19 AM,
#19
RE: I2C 4x20 display with OTG and Micro
Hi Dale,

was the output you quote in the IDE output window or was it in the stdout file? If it is not the latter have you looked at the stdout file in the /source folder within the main Pinguino Folder? The stdout file usually gives a far more complete list of messages during the IDE compile process. What is most important are any errors reported in the stdout file. There may also be some warnings but these do not normally stop the compile process from completing, although they may indicate other problems with your program or possibly some of the library functions.

Regards
Board = PIC32-Pinguino-OTG Rev C
OS = Linux Unbuntu 11.10 till 26 Apr 2012
OS = Linux Unbuntu 12:04 from 27 Apr 2012
Reply
23-04-2012, 10:26 AM, (This post was last modified: 23-04-2012, 10:27 AM by pingotg.)
#20
RE: I2C 4x20 display with OTG and Micro
Without knowing the errors I'm struggling!!

One thing it may be is that
#include <file>
has a specific meaning and you may mean
#include "file"

The former only searches special (C compiler-defined) places (which are usually directories but need not be), whereas the latter searches places you can specify and which I think automatically includes where the main file being compiled was found -- you'll start to need to read up on C to be honest.

It may be that the IDE automatically asks the compiler to look in extra places including where you've put NHD.c but it also may not do that.

(Try using quotes i.e. "NHD.c" if the errors show it's not being found.)

John
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)