Pages: 1 [2] 3   Go Down
Author Topic: 'High' voltage 7-seg LED interface  (Read 3119 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That worked!! I now have it counting from 00 to 99 smiley

Annoyingly and stupidly, I mananged to under order the resistors so I can't do more then 2 displays at the moment. Dead chuffed that it is working as planed at the moment. Next job is to try and get it to work on the larger displays now with the different voltages.

Logged

Norman, OK, USA!
Offline Offline
Full Member
***
Karma: 0
Posts: 127
Klingon Machinist
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't know about anybody else but I cannot view your Y-T videos as they are labeled as 'private'.
Logged

M.S.

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ooops meant to put them up simply as unlisted [smiley=embarassed.gif] not private. Changed now! smiley

BTW they aren't anything exciting, I am just a little proud that with the help of these guys that it actually works. Normally I have a great idea then can't figure out how to make it function!

I am hoping to find a way of making a library to make it easier to display using shift-reg's as I am not aware of one. Plus makes it easier it implement on any future projects I may have.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Okay so have everything wired up and it is working - sort of.

I seem to be getting a 'shadowing' across the displays. The following should be displaying 230:


And it is, however it also seems to be showing the previous digits as well. The camera doesn't pick up the light differences too well. You can see that there is a 230 displayed as they are brighter. The remaining LEDs are at about 25-50% brightness.

As far as I can figure this is an issue with the way that I am using the shift registers with a common cathode display, as suggested by Graynomad. I can't use the G line to blank the display while updating (if G goes high to blank the display all the outputs switch off thus actually turning on all the LEDs), so you are seeing the effect of the other numbers being pushed down the shift registers.

The only other way I can think of is to cut power to the GND of the displays as the screen updates using a transistor. I was hoping though that someone else may have an alternative solution that could be applied in software.

For those interested here is a picture of the minute board:
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Solved the ghost problem. Have put a transistor into the ground line for the displays. Now the Adruino can turn off the displays while it updates. Only downside is a reduction in brightness. Have to wait until tomorrow to see how that affects the readability in daylight.
Logged

Norman, OK, USA!
Offline Offline
Full Member
***
Karma: 0
Posts: 127
Klingon Machinist
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks. I have a project coming up with higher voltage LED displays so I am watching this.

smiley
Logged

M.S.

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 129
Posts: 8530
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I did say that the idea was

Quote
Off the top of my head mind, I haven't tried it but it should work
but I still reckon it should work without without having to turn the displays off.

Are you sure you're only latching the SRs at the end of the data stream?

Can you post the actual circuit and code?
Logged

Rob Gray aka the GRAYnomad www.robgray.com

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry Graynomad, just re-read my post and didn't meant to sound like I was blaming you! I am enjoying the challenge smiley-grin

I'll get a circuit and the code up tomorrow (well later today as it is 12.30am  ;D). Code is still a little messy at the moment, but will put it up in current state.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is the circuit diagram. Each display is the same.




Code (once I have it all working correctly I plan to tidy this up a lot, just want to fix one problem at a time). I borrowed the button check function for testing for a long press (sorry can't remember where on the web I found it  :-[). The clock came from Rob Faludi and his open source clock.

Code:
/*
Count Down Timer
 
 Usage - Three buttons: Mode, Hour and Minute.
 
 Short press Mode = Start/Pause timer
 Long press Mode (2.5sec) = Enter/exit timer setting mode
 
 With timer paused press Minute and Hour together to reset clock
 
 In Timer Setting mode, press Hour/Minute to increment time settings.
 
 */

#define timeroffest -3 //adjustment for error in timing

#define resetPin 8
#define minutePin 9
#define hourPin 10

#define debounce 50                       // ms debounce period to prevent flickering when pressing or releasing the button
#define holdTime 2500                     // ms hold period: how long to wait for press+hold event

#define Tserial 4
#define Tclk 6
#define Trck 5
#define dBlank 7  // pin to blank display - low = display off - high = display on

byte character[10] = {
  B01000010, B11101110, B11000001, B11000100, B01101100, B01010100, B01010000, B11001110, B01000000, B01001100};

boolean runMode = false;
boolean setMode = false;
boolean run=0, reset=0;

int second=0, minute=0, hour=0; // declare working time variables

int sMin=30, sHour=2; //declare set time variables



void setup() {
  pinMode(resetPin, INPUT); //pins for normally closed switches to set the time
  pinMode(minutePin, INPUT);
  pinMode(hourPin, INPUT);
  digitalWrite(resetPin, HIGH); // writing an input high turns on pull-up resistors
  digitalWrite(minutePin, HIGH);
  digitalWrite(hourPin, HIGH);

  pinMode(Tserial, OUTPUT);
  pinMode(Tclk, OUTPUT);
  pinMode(Trck, OUTPUT);
  pinMode(dBlank, OUTPUT);

  digitalWrite(Trck, LOW);
  digitalWrite(dBlank, LOW);

  minute = sMin;
  hour = sHour;
}

void loop() {

  if (second == 0 && minute == 0 && hour == 0 || runMode == 0) {
    if (setMode == false) displayOut(false);
  }
  else if (setMode == false) {
    clock();
    displayOut(false);
  }

  if (setMode == true) {
    setTime();
    displayOut(true);
  }

  if (runMode == 0 && reset == 1) {
    second =0;
    minute = sMin;
    hour = sHour;
    reset = 0;
  }


  checkButtons(); // runs a function that checks the setting buttons
}














void setTime() {
  static boolean minStat = false, hrStat = false;
  int minBut, hrBut;

  minBut = digitalRead(minutePin);
  hrBut = digitalRead(hourPin);

  if (hrBut == LOW && hrStat == false) {
    sHour = sHour + 1;
    if (sHour > 9) sHour = 0;
    hrStat = true;
  }
  if (hrBut == HIGH && hrStat == true) {
    hrStat=false;
  }

  if (minBut == LOW && minStat == false) {
    sMin = sMin + 1;
    if (sMin > 59) sMin = 0;
    minStat = true;
  }
  if (minBut == HIGH && minStat == true) {
    minStat=false;
  }

  hour = sHour;
  minute = sMin;
  second = 0;
}




void checkButtons() {

  static long btnDnTime;                           // time the button was pressed down
  static long btnUpTime;                           // time the button was released
  static boolean ignoreUp = false;                 // whether to ignore the button release because the click+hold was triggered
  static int R = 0;                                 //Mode button state
  static int Rstate = 0;

  R = digitalRead(resetPin);                   //read Mode button state    
  //Test for button pressed and store the down time
  if (R == LOW && Rstate == HIGH && (millis() - btnUpTime) > long(debounce))
  {
    btnDnTime = millis();
  }
  //Test for button release and store the up time
  if (R == HIGH && Rstate == LOW && (millis() - btnDnTime) > long(debounce) && setMode == false)
  {
    if (ignoreUp == false) runMode = !runMode;      //test if Low-High set mode should be toggled
    else ignoreUp = false;
    btnUpTime = millis();
  }
  //Test for button held down for longer than the hold time
  if (R == LOW && (millis() - btnDnTime) > long(holdTime))
  {
    setMode = !setMode;                  //toggle Set mode to Timing mode or vice versa
    runMode = 0;
    ignoreUp = true;
    btnDnTime = millis();
  }
  Rstate = R;

  if (runMode == 0) {
    if (digitalRead(minutePin) == LOW && digitalRead(hourPin) == LOW) reset = 1;
  }

}




void clock() {
  static unsigned long lastTick = 0; // set up a local variable to hold the last time we moved forward one second
  // (static variables are initialized once and keep their values between function calls)

  // move forward one second every 1000 milliseconds
  if (millis() - lastTick >= 1000+timeroffest) {
    lastTick = millis();
    second--;
  }

  // move back one minute every 60 seconds
  if (second < 0) {
    minute--;
    second = 59; // reset seconds to zero
  }

  // move back one hour every 60 minutes
  if (minute < 0) {
    hour--;
    minute = 59; // reset minutes to zero}
  }

  if (hour < 0) {
    hour = 0; // reset hours to zero
  }

}




void displayOut(boolean set) {
  byte output;
  byte minH;
  byte minL;
  byte hourL;
  static byte secFlash, secReg;
  static unsigned long update = 0;

  if (millis() - update >= 100) {
    
  hourL = hour;
  minH = minute / 10;
  minL = minute % 10;

  digitalWrite(dBlank, LOW);

  output = character[minL];

  if(setMode==true) {
    bitClear(output, 6);
  }

  for(int c=0; c<=7; c++)
  {
    digitalWrite(Tserial, bitRead(output, c));
    digitalWrite(Tclk, HIGH);
    digitalWrite(Tclk, LOW);
  }

  output = character[minH];
  for(int c=0; c<=7; c++)
  {
    digitalWrite(Tserial, bitRead(output, c));
    digitalWrite(Tclk, HIGH);
    digitalWrite(Tclk, LOW);
  }
  digitalWrite(Trck, HIGH);
  digitalWrite(Trck, LOW);

  output = character[hourL];
  
  if (secFlash != second) {
    secReg = !secReg;
    secFlash = second;
  }
  
  bitWrite(output, 6, secReg);
  
  for(int c=0; c<=7; c++)
  {
    digitalWrite(Tserial, bitRead(output, c));
    digitalWrite(Tclk, HIGH);
    digitalWrite(Tclk, LOW);
  }
  digitalWrite(Trck, HIGH);
  digitalWrite(Trck, LOW);

  digitalWrite(dBlank, HIGH);
  }
}
« Last Edit: August 03, 2010, 02:51:03 am by smartroad » Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 129
Posts: 8530
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Got that, I'm about to have dinner but two things that look a little suss in the displayOut function are

Code:
 for(int c=0; c<=7; c++)
  {
    digitalWrite(Tserial, bitRead(output, c));
    digitalWrite(Tclk, HIGH);
    digitalWrite(Tclk, LOW);
  }
  digitalWrite(Trck, HIGH);
  digitalWrite(Trck, LOW);

Won't this produce 9 pulses on Trck?

and

Code:
 bitWrite(output, 6, secReg);
The DP is connected to bit 7, doesn't this set bit 6?

I'll have a closer look later tonight.

Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Trck is outside of the for loop so should only pulse once after each loop completion. Thinking about that, I should only need to toggle Trck at the end of the display run rather then after each loop.

Ignore the pins connections between the IC and LED. I had to adjust the pin connections on the breadboard to keep the wiring simple. Bit 6 is the DP on the prototype.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ahhh solved brightness issue.

Where I had added the blanking for the display at the beginning of the displayout, i also added a delay to reduce the number of times it updated the display.

Code:
if (millis() - update >= 500) {

I forgot to update "update" with the current millis() value when the IF statement was true. So it updated the screen every time it was run.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@Mr. Swarf

Glad to help smiley I would strongly suggest that you use common anode though, makes it much easier!
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 129
Posts: 8530
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Trck is outside of the for loop
Oops, didn't notice the different spelling.

Quote
Thinking about that, I should only need to toggle Trck at the end of the display run rather then after each loop.

That's right.

I found the code difficult to read and a bit long-winded with local variables that really didn't do anything, so can I suggest something like this

Code:
#define DP_BIT B01000000

void displayOut() {

  byte dp_bit = 0;

  static byte secFlash;
  static unsigned long update = 0;

  if (millis() - update >= 100) {
    
          if (secFlash != second) {
            dp_bit ^= DP_BIT;     // toggle the DP bit
            secFlash = second;
        }

        outputChar(character[minute / 10]);
        outputChar(character[minute % 10]);
        outputChar(character[hour] != dp_bit);
        
        digitalWrite(Trck, HIGH);      // latch data to OPs
        digitalWrite(Trck, LOW);
  }
}
  

 void outputChar(byte c) {
      for(int i=0; i<=7; i++) {
            digitalWrite(Tserial, bitRead(c, i));
            digitalWrite(Tclk, HIGH);
            digitalWrite(Tclk, LOW);
      }
 }

I haven't seriously researched your routine or tested this but am sure this will do the same. You shouldn't need to blank the display.

Also, I think it's fair to say that normal coding practice is to UPPER_CASE any constants (#defines), that way when you look at a piece of code you know that for example HOLD_TIME is a constant and you don't go looking for it's declaration or any code that changes it.

Quote
I would strongly suggest that you use common anode though, makes it much easier
I second that  smiley

Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That works. Had to change
Code:
outputChar(character[hour] != dp_bit);
to
Code:
outputChar(character[hour] ^= dp_bit);
to get it to work.

However it now seems to turn the DP on minute/10 follows the hour DP a fraction of a second after. It is only the "/10" not the "%10"
Logged

Pages: 1 [2] 3   Go Up
Jump to: