Adafruit #570 in Inc 5000 & #11 in manufacturing - fastest-growing private companies in America - INC 5000 - Read more!

Re: Help with I2C Control of 4-Digit 7-Segment Display w/I2C Backpack

by vortex on Sun Jan 27, 2013 6:23 pm

Code here includes working commands for talking to an 8 relay board over i2c. Using the code below, junk is printed to the LCD. The code looks like:
Code: Select all | TOGGLE FULL SIZE
// Test file to connect to a 7 segment Adafruit LED
// display over i2c and test it.
//
//
//

#include <iostream>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdint.h>
#include "i2c-dev.h"

using namespace std;

#define SEVEN_SEG_LCD_0 0x70
#define SEVEN_SEG_LCD_1 0x71

static const uint8_t numbertable[] = {
   0x3F, /* 0 */
   0x06, /* 1 */
   0x5B, /* 2 */
   0x4F, /* 3 */
   0x66, /* 4 */
   0x6D, /* 5 */
   0x7D, /* 6 */
   0x07, /* 7 */
   0x7F, /* 8 */
   0x6F, /* 9 */
   0x77, /* a */
   0x7C, /* b */
   0x39, /* C */
   0x5E, /* d */
   0x79, /* E */
   0x71, /* F */
};

uint16_t displaybuffer[8];
int file;

int beginTransmission();
void endTransmission();
void startOscillator();
void displayOnBlinkOff();
void setBrightness();
void sendCharacters();


int main() {

   startOscillator();
   displayOnBlinkOff();
   setBrightness();
   sendCharacters();

}

int beginTransmission() {

   // BeagleBone specific I2C bus
   if ((file = open("/dev/i2c-3", O_RDWR)) < 0) {
      cout << "Failed to open connection to the I2C Bus" << endl;
      return (1);
   }

   if (ioctl(file, I2C_SLAVE, SEVEN_SEG_LCD_1) < 0) {
      cout << "I2C_SLAVE address " << SEVEN_SEG_LCD_1 << " failed..." << endl;
      return (2);
   }

   return 1;
}

void endTransmission() {
   close(file);
}

void startOscillator() {
   beginTransmission();
   i2c_smbus_write_byte(file, 0x21);
   endTransmission();
}

void displayOnBlinkOff() {
   beginTransmission();
   i2c_smbus_write_byte(file, 0x80 | 0x01 | (0 << 1));
   endTransmission();
}

void setBrightness() {
   beginTransmission();
   i2c_smbus_write_byte(file, 0xE0 | 15);
   endTransmission();
}

void sendCharacters() {

   beginTransmission();

   displaybuffer[0] = 0x3F; // 0
   displaybuffer[1] = 0x06; // 1
   displaybuffer[2] = 0x00; // colon off
   displaybuffer[3] = 0x5B; // 2
   displaybuffer[4] = 0x4F; // 3

   for (uint8_t i=0; i<8; i++) {
      //Wire.write(displaybuffer[i] & 0xFF);
      i2c_smbus_write_byte(file, displaybuffer[i] & 0xFF);
   }

   endTransmission();
}

vortex
 
Posts: 8
Joined: Sun Sep 30, 2012 9:05 pm

Re: Help with I2C Control of 4-Digit 7-Segment Display w/I2C Backpack

by vortex on Mon Jan 28, 2013 5:52 am

Have been playing around and refactored slightly, now 3 out of 4 characters are working OK. Not sure why the last one is always displaying as 0

Code: Select all | TOGGLE FULL SIZE
// Test file to connect to a 7 segment Adafruit LED
// display over i2c and test it.
//
//
//

#include <iostream>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdint.h>
#include "i2c-dev.h"

using namespace std;

#define SEVEN_SEG_LCD_1 0x71 //30a Relay Board

uint16_t displaybuffer[8];
int file;

int beginTransmission();
void endTransmission();
void sendCharacters();

int main() {
   sendCharacters();
}

int beginTransmission() {

   // BeagleBone specific I2C bus
   if ((file = open("/dev/i2c-3", O_RDWR)) < 0) {
      cout << "Failed to open connection to the I2C Bus" << endl;
      return (1);
   }

   if (ioctl(file, I2C_SLAVE, SEVEN_SEG_LCD_1) < 0) {
      cout << "I2C_SLAVE address " << SEVEN_SEG_LCD_1 << " failed..." << endl;
      return (2);
   }

   return 1;
}

void endTransmission() {
   close(file);
}

void sendCharacters() {

   beginTransmission();

   i2c_smbus_write_byte(file, 0x21); // start oscillator
   i2c_smbus_write_byte(file, 0x81); // display on, blink off
   i2c_smbus_write_byte(file, 0xEF); // set brightness to max

   i2c_smbus_write_byte(file, 0x00); // starting RAM Address

   cout << "First numbers " << endl;

   displaybuffer[0] = 0x3F; // 0
   displaybuffer[1] = 0x06; // 1
   displaybuffer[2] = 0x00; // colon off
   displaybuffer[3] = 0x5B; // 2
   displaybuffer[4] = 0x4F; // 3

   i2c_smbus_write_i2c_block_data(file, 0x00, 8, (__u8 *)displaybuffer);

   sleep(4);

   cout << "Second numbers" << endl;

   displaybuffer[0] = 0x7C; // b
   displaybuffer[1] = 0x79; // E
   displaybuffer[2] = 0x00; // colon off
   displaybuffer[3] = 0x79; // E
   displaybuffer[4] = 0x71; // F

   i2c_smbus_write_i2c_block_data(file, 0x00, 8, (__u8 *)displaybuffer);

   endTransmission();
}


The 7seg should show 0123 and then 4 seconds later show bEEF but, it shows 01230 and then bEE0. Unsure why.

Does anyone have any suggestions?
vortex
 
Posts: 8
Joined: Sun Sep 30, 2012 9:05 pm

Re: Help with I2C Control of 4-Digit 7-Segment Display w/I2C Backpack

by High-Fidelity on Tue Jan 29, 2013 5:31 am

Does the i2c_smbus_write_i2c_block_data function send the high or low 8 bits of each value in the displaybuffer first? It may be that it's sending the wrong bits initially. The low bits must be sent first (they're the ones connected to the segment). If it's sending the high bits first, then that may be the issue.

When I did this, I was sending them as follows:

Code: Select all | TOGGLE FULL SIZE
i2c_write(0x70 << 1 + 0x00); // send the address
i2c_write(0x00); //starting register
for (int i = 0; i < 8; i++) {
   i2c_write(displayBuffer[i] & 0xFF);
   i2c_write(displayBuffer[i] >> 8);
}


I do it in a series of discrete 8 bit transfers.

The project I'm working on is a Peugeot 206 GTi, which has currently ground to an exacting and complete halt! It turns out that when I wrote this up last year that my wife was pregnant with our second child and I rather grossly underestimated the time required to look after 2 babies under 1.5 years!

Anyway, the idea was that I was developing a monitoring box that has a 20Hz GPS, accelerometer and gyrometer which would interface with a MegaSquirt V3 ECU controlling the car's fuel and spark. Since the plan was for it to be a dedicated track car, the work I was doing would substitute as a dash and datalogger. It would also provide a synchronised trigger to a couple of GoPro cameras scattered around the car.

At this stage, the 206 will be going back on the road, ready to drive another few 10's of thousands of kilometres until I find enough time to do the work to turn it into a track car. Mechanically it was getting pretty close, but electrically and safety wise, it still had someway to go, and they're the bigger jobs, so back to the road it goes for now.

Have attached my code here. It will need some additional files to compile as is, but it should be enough to show how it works.
i2c.tar.gz
i2c source
(2.21 KiB) Downloaded 48 times
High-Fidelity
 
Posts: 4
Joined: Mon Jun 18, 2012 8:04 am

Re: Help with I2C Control of 4-Digit 7-Segment Display w/I2C Backpack

by vortex on Thu Jan 31, 2013 7:10 pm

Wow thanks for the code! One thing I have run into is that it looks like the i2c code isn't sending a stop bit. My display gets confused sometimes when I play around with different options, but unplugging it doesn't fix it.

Actually perhaps it's the i2c bus that's getting confused?

Anyway I'm not sure how to send a stop bit. Your code has it but clearly the stm32 is different to on Linux, but the character must be the same surely?
vortex
 
Posts: 8
Joined: Sun Sep 30, 2012 9:05 pm

Re: Help with I2C Control of 4-Digit 7-Segment Display w/I2C Backpack

by High-Fidelity on Fri Feb 01, 2013 5:55 am

According to http://www.mjmwired.net/kernel/Document ... s-protocol the i2c_smbus_write_i2c_block_data function will do the stop for you, so you shouldn't need to worry about.

Not really sure what else could be the problem. I recommend giving it a go byte by byte and see if you can make it work like that. Once you've got that working, it shouldn't be too difficult to turn it into a block write operation.

I'm now playing with these displays on an LPC1114 for a little home project.
High-Fidelity
 
Posts: 4
Joined: Mon Jun 18, 2012 8:04 am

Re: Help with I2C Control of 4-Digit 7-Segment Display w/I2C Backpack

by High-Fidelity on Fri Feb 01, 2013 5:56 am

One thing I should have mentioned... I verified that I was getting what I wanted on the i2c bus by using an el cheapo usb logic analyser. It may be worth trying the same if you're having problems.
High-Fidelity
 
Posts: 4
Joined: Mon Jun 18, 2012 8:04 am

Re: Help with I2C Control of 4-Digit 7-Segment Display w/I2C Backpack

by vortex on Fri Mar 29, 2013 6:22 pm

I finally managed to get back to having another look at this problem today (haven't been able to look at it since February for various reasons, mostly laziness and lack of motivation).

I fixed the issue :)
For reasons I don't fully understand, when I used the code like this:
Code: Select all | TOGGLE FULL SIZE
      displaybuffer[0] = 0x02 | 0x80; // add a decimal point to this one
      displaybuffer[1] = 0x02 | 0x80; // add a decimal point to this one
      displaybuffer[2] = 0xFF; // colon.
      displaybuffer[3] = 0x02;
      displaybuffer[4] = 0x02;
      i2c_smbus_write_i2c_block_data(file, 0x00, 8, (__u8 *)displaybuffer);


The final number/letter would never work. I thought well perhaps I'm overflowing the buffer - I changed the length value from 8, to 4, lo-and behold only the first two digits only worked. A result, it looks like 8 may even be too short. Changed it to 10:
Code: Select all | TOGGLE FULL SIZE
      displaybuffer[0] = 0x02 | 0x80; // add a decimal point to this one
      displaybuffer[1] = 0x02 | 0x80; // add a decimal point to this one
      displaybuffer[2] = 0xFF; // colon.
      displaybuffer[3] = 0x02;
      displaybuffer[4] = 0x02;
      i2c_smbus_write_i2c_block_data(file, 0x00, 10, (__u8 *)displaybuffer);


And the last digit began to work!

Trap for young players!
vortex
 
Posts: 8
Joined: Sun Sep 30, 2012 9:05 pm

Re: Help with I2C Control of 4-Digit 7-Segment Display w/I2C Backpack

by vortex on Fri Mar 29, 2013 6:28 pm

It should be said, that now I know what that variable is for, the better way would be to use sizeof() thus:
Code: Select all | TOGGLE FULL SIZE
      displaybuffer[0] = 0x01 | 0x80; // add a decimal point to this one
      displaybuffer[1] = 0x01 | 0x80; // add a decimal point to this one
      displaybuffer[2] = 0xFF; // colon.
      displaybuffer[3] = 0x01;
      displaybuffer[4] = 0x01;
      i2c_smbus_write_i2c_block_data(file, 0x00, sizeof(displaybuffer), (__u8 *)displaybuffer);
vortex
 
Posts: 8
Joined: Sun Sep 30, 2012 9:05 pm

Re: Help with I2C Control of 4-Digit 7-Segment Display w/I2C Backpack

by Numerius_Negidius on Sun Jun 02, 2013 3:30 pm

Hi,

I'm trying to access the Display using only the Wire library. I'd like to display High-Fidelity's Fuel message, the following code, however, does not work. What am I missing?
Code: Select all | TOGGLE FULL SIZE
#include <Wire.h>


void setup(){
  Wire.begin();
  Serial.begin(9600);



 Wire.beginTransmission(0x70);
 Wire.write(0x21);
 Wire.write(0xEF);
 Wire.write(0x85);
 Wire.write(0x00);
Wire.write(0x71);
Wire.write(0x3E);
Wire.write(0x00);
Wire.write(0x79);
Wire.write(0x38);
Wire.endTransmission();
}

void loop(){
}


Thank you very much!


Edit: Anyone?
Numerius_Negidius
 
Posts: 4
Joined: Sun Jun 02, 2013 3:25 pm

Re: Help with I2C Control of 4-Digit 7-Segment Display w/I2C Backpack

by Numerius_Negidius on Tue Jun 04, 2013 3:46 pm

Anyone? Pretty please?
Numerius_Negidius
 
Posts: 4
Joined: Sun Jun 02, 2013 3:25 pm

Re: Help with I2C Control of 4-Digit 7-Segment Display w/I2C Backpack

by adafruit_support_mike on Tue Jun 04, 2013 6:47 pm

Hi - When you have a question, it's best to post a new topic than adding to the end of one that already exists. The new ones get our attention first, then if we have time we'll do a sweep through the other threads to look for stragglers.

WRT the code, I don't see anything immediately wrong. The general transmission sequence looks good, the address is right, and while I haven't translated the data values they should at least do something.

Let's test your wiring and hardware by dropping back to a known configuration and seeing if that works. Load the Adafruit sevenseg.ino sketch into your Arduino and see if that makes the display do what it should.

If you need the sketch, it's here: https://github.com/adafruit/Adafruit-LE ... venseg.ino , and the library is just up the file tree from there.
When you void a product warranty, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
adafruit_support_mike
 
Posts: 8966
Joined: Thu Feb 11, 2010 1:51 pm

Re: Help with I2C Control of 4-Digit 7-Segment Display w/I2C Backpack

by Numerius_Negidius on Thu Jun 06, 2013 3:46 pm

Hm, the Adafruit code works just fine. I've also tried the code with an Attiny2313 (using an AVR library), the code definitely responds via I²C, because the Attiny doesn't keep sending the address (I would see this on the oscilloscope). Must be something with the commands themselves :(
Numerius_Negidius
 
Posts: 4
Joined: Sun Jun 02, 2013 3:25 pm

Re: Help with I2C Control of 4-Digit 7-Segment Display w/I2C Backpack

by adafruit_support_mike on Mon Jun 10, 2013 6:07 pm

Looking at the code above in the page, you seem to have the blink rate and brightness settings reversed. Try this:

Code: Select all | TOGGLE FULL SIZE
Wire.write( 0x21 );    //  start the oscillator
Wire.write( 0x81 );    //  display on, blink off
Wire.write( 0xEF );    //  brightness to maximum
Wire.write( 0x00 );    //  start at RAM address 0
Wire.write( 0x7C );    //  b
Wire.write( 0x79 );    //  E
Wire.write( 0x00 );    //  decimal point off
Wire.write( 0x79 );    //  E
Wire.write( 0x71 );    //  F
When you void a product warranty, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
adafruit_support_mike
 
Posts: 8966
Joined: Thu Feb 11, 2010 1:51 pm

Re: Help with I2C Control of 4-Digit 7-Segment Display w/I2C Backpack

by Numerius_Negidius on Tue Jun 25, 2013 2:29 pm

OK, I got it now: Each write to a register (like the oscillator or the display enable) need to be prefaced with an own START condition :oops:
Numerius_Negidius
 
Posts: 4
Joined: Sun Jun 02, 2013 3:25 pm