Smooth Charlieplexing
Posted: Wed Jun 15, 2016 7:17 am
Hi
I am putting together a project that will display some numbers on some 7 segment displays. I am trying to charlieplex the 7 segment displays as this minimises the number of shift registers required.
I have code working using a Ticker that alternates 2 of the bits on the 2nd shift register which in turn activate 2 2n7000's that grounds just 1 of the 7segment displays at once.
The problem is the leds sort of pulsate a bit. The refresh rate seems ok (50hz). I suspect the ESP8266 is doing some other work and delaying the Ticker which makes one of the segments glow slightly longer causing this pulsating.
I couldn't find any examples of anyone doing what I am doing. I have tried varying the Ticker timer down to 1000 times per second (500hz) with no improvement.
code:
I have cut this down to the bare minimum, each 7seg hard coded with a number to display for testing.
I am putting together a project that will display some numbers on some 7 segment displays. I am trying to charlieplex the 7 segment displays as this minimises the number of shift registers required.
I have code working using a Ticker that alternates 2 of the bits on the 2nd shift register which in turn activate 2 2n7000's that grounds just 1 of the 7segment displays at once.
The problem is the leds sort of pulsate a bit. The refresh rate seems ok (50hz). I suspect the ESP8266 is doing some other work and delaying the Ticker which makes one of the segments glow slightly longer causing this pulsating.
I couldn't find any examples of anyone doing what I am doing. I have tried varying the Ticker timer down to 1000 times per second (500hz) with no improvement.
code:
I have cut this down to the bare minimum, each 7seg hard coded with a number to display for testing.
Code: Select all
#include <Ticker.h>
#define CLOCK 12
#define LATCH 13
#define DATA 15
Ticker charliePlexTicker;
uint8_t segment[3];
uint8_t segmentFlag = 0;
uint8_t counter = 0;
void setup() {
pinMode(DATA, OUTPUT);
pinMode(CLOCK, OUTPUT);
pinMode(LATCH, OUTPUT);
charliePlexTicker.attach(0.008,charliePlex);
segment[0] = 8;
segment[1] = 9;
}
// mapping of numbers to shift regster output
const uint8_t seg[11] = {
0b01110111,
0b01000001,
0b01101110,
0b01101011,
0b01011001,
0b00111011,
0b00111111,
0b01100001,
0b01111111,
0b01111011,
0b10000000
};
void loop() {
}
void charliePlex(){
segmentFlag ^= 1;
if (segmentFlag) {
shiftOutFast(0b10000000);
shiftOutFast(seg[segment[1]]);
} else {
shiftOutFast(0b01000000);
shiftOutFast(seg[segment[0]]);
}
latch();
}
//********************************************************************************************************
void latch() { // trigger latch
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, 1 << LATCH);
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, 1 << LATCH);
}
//********************************************************************************************************
// function found here http://nerdralph.blogspot.com.au/2015/04/a-4mbps-shiftout-for-esp8266arduino.html 4mbit shift out
void shiftOutFast(byte data)
{
byte i = 8;
do{
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, 1 << CLOCK);
if(data & 0x01)
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, 1 << DATA);
else
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, 1 << DATA);
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, 1 << CLOCK);
data >>= 1;
}while(--i);
return;
}