Multiplex ghosting issue

Thread Starter

coldpenguin

Joined Apr 18, 2010
165
I am trying to do a circuit to help to cool a water resevoir. The cooling element will be a peltier.

Intention was to:
use 3 DS1820 devices to read temp of water plate, (perltier sandwiched), temp of 'hot' plate, and 1 to read ambient.
Then depending on whether there is a suitable difference (function to be decided upon), then I PWM on the peltier.
Output was going to be displayed on 3 7-segment displays, i.e. two degrees celcius+. plus one decimal place.
Once per a suitable time-frame, I was going to move between the temperature displayed, so I was going to use 3 other LEDs to indicate which temperature is visible.
I am starting to prototype, and will eventually end up with a circuit like the attached schematic, except hopefully without bugs.

I have wired up 3 displays, by connecting the equal pins first (i.e. a to a, to a) and then to the resistor and then to the PIC. This is on breadboard.
On the input side, I put 4 transistors along the edge of the board, connected the collectors together and then to +5V.
As I am starting to build the prototype, I have not added any other components, I am using the ICSP for power, have not put in the regulators yet, and am driving the transistors directly (base) from pins RA0,1,2,3 of the PIC. I am not determining temperature yet, and am not yet using the other components (or have them on the breadboard). Note, I am not using the logic gates yet, these cannot be slowing down the transistors.

Problem:
First three digits worked fine, I added one at a time by connecting the base to the relevant pin on the PIC.
When I added the fourth pin to the base of the transistor, I am starting to see ghosting on the second digit of the display. Disconnecting it, I notice that there is in fact a slight blip when the point is visible too.

Any ideas on what I am doing wrong? I don't think this is a timing issue in the code as such (as I would have thought it would affect the first digit, i.e. t[0] not t[1] when I add t[3]), have I somehow got capacitance on the lines? I didn't think that it would be large enough to partially light (seems about 50%) two wrong segments on a display.
Code is really simple at the moment, I have removed the creation of the arrays, numbers stores the pins to display a number/letter, t[] defines which pin (which will later be pin-set) is used to activate the transistor. Currently I have 4 LEDs for the 4th 'digit', speaker will come later (replacing the LED).
Rich (BB code):
main{ TRSIB=0x00;TRISA=0x00;
...
    while(1){
o[3]=0b00001111;

o[0]=numbers[y];
o[1]=numbers[y+1];
o[2]=numbers[y+2];
        int k=0;
        while(k<10){
            int i=0;
            while(i<1600){
                i++;
                output(o,i);
             }
          k++;
          }
     y++;
     if(y>7){y=0;}
    }
}
output(char * o,int i){
 int j=0;
 for(int j=0;j<4;j++){
  PORTA=t[j];
  if(i>800 && j==1){
   PORTB=o[j]-0b10000000;
  }else{
   PORTB=o[j];
  }
  PORTA=t[j];
  if(i>800 && j==1){
   PORTB=o[j]-0b10000000;
  }else{
   PORTB=o[j];
  }
  PORTA=0x00;
  PORTB=0xFF;
 } //End for
}
Whilst writing this up, I have realised that I have neglected to put a resistor between the PIC and the transistors. Is this an issue, it would affect how quickly (slightly) and how much current is let through.



BTW. Other components not in place, and not relevant to the problem:
X1 will connect to the DS1820 devices.
PELTIERCONNECT, will connect to the peltier
RELAYCONN is connected to a relay which needs a 12V source for the coil, this 12V will be in parallel to the 12V used for the source to the two regulators in this circuit (and on to the Peltier). The power through the relay will be AC, this relay etc. is outside of the project, but, I want to use the hall sensor A1323UA to confirm that the AC has current flowing.
The switch was in there in case I needed to disconnect RB6/7 for the ICSP, doesn't seem to be necessary so it will disappear,
 

Attachments

Last edited:

bretm

Joined Feb 6, 2012
152
I would expect ghosting from that code. You're setting porta to a new value, switching to a different digit, while portb still contains the previous digit's segments, and the previous digits weren't displayed for any appreciable amount of time.

If you put in a 6ms delay after setting portb, the segments will remain lit long enough to allow persistence of vision to kick in. Ideally you should also turn off all segments before switching to the next digit, but with the added delay that might not be necessary.

With a delay, you also probably wouldn't want to loop 1600 times.
 

Thread Starter

coldpenguin

Joined Apr 18, 2010
165
Sorry, can you confirm where I am changing PORTA whilst B is still active? (and I mean that without sarcasm)

I am either missing something obvious in what I have done, or possibly I have badly explained it.

As I am using a common anode, I am having to toggle the segments ON by setting the pins LOW on port B.

I believe, that prior to moving within the digit loop for port A, I am setting A to nothing ON (i.e. all transistors off), and the setting B to everything on, (i.e. all segments off).

Then I loop to the next j
I duplicated the ports set within the loop to increase the delay period, I believe that the delay period between A on and A off should be a minimum of 7 instruction cycles, which given I am using a 4MHz oscilator with this chip should equate to one us per cycle, i.e. 7us
 

bretm

Joined Feb 6, 2012
152
You're right, i misread the code. The indenting made it look like the for loop only enclosed the first portb assignment.

I'm not sure why there's ghosting, then. Is there a reason you set porta equal to t[j] twice within the loop? And i'm assuming t[j] contains the correct values. I don't see the code that sets that up.
 

bretm

Joined Feb 6, 2012
152
Grr, i edited my post but it didn't seem to take.

I see j declared before the loop, and declared again in the for statement. Does that even compile?
 

Thread Starter

coldpenguin

Joined Apr 18, 2010
165
You're right, i misread the code. The indenting made it look like the for loop only enclosed the first portb assignment.
Sorry about that, I'll edit the post. I program without any indentation, and added the indents 'to help' to the posted code only.

I'm not sure why there's ghosting, then. Is there a reason you set porta equal to t[j] twice within the loop?
Only to add a suitable delay, without it I reckon the delay of the loop was only around 3us, which meant a visible, but dull response. I hadn't added any delay routines yet, as the sensors I am using, the DS1820 require a specific timing signal, which often means 'tweaking' delays manually whilst checking with a logic probe. I have had issues with using generic delays when using 1-wire communications.


Grr, i edited my post but it didn't seem to take.
I see j declared before the loop, and declared again in the for statement. Does that even compile?
Yup it compiles, because it is saparate scopes. The 'output' function was originally inline to the main code, and I had started to write a new version within the routine when I copied the original code in.

I didn't put t and numbers in the code above, as it is pretty boring.
The array t[] is currently not correct for the schamatic, I have not used the logic gates yet, as I like to build fro mthe ground up, especialy as this particular PIC does not support debugging, I wanted to make sure I had a working 'output' routine.
You are missing the following for a complete code:
Rich (BB code):
#include <pic.h>
#include <stdio.h>
#include <stdlib.h>
#define sleep()        asm("sleep")

__CONFIG( FOSC_HS & WDTE_OFF);

char numbers[16];
char t[4];
//and in main:
t[0]=0b00000001;
t[1]=0b00000010;
t[2]=0b00000100;
t[3]=0b00001000;
    char o[4];                        
        TRISA=0b00000000;
        TRISB=0b00000000;
numbers[1]=0b11111001;
numbers[2]=0b10100100;
numbers[3]=0b10110000;
numbers[4]=0b10011001;
numbers[5]=0b10010010;
numbers[6]=0b10000010;
numbers[7]=0b11111000;
numbers[8]=0b10000000;
numbers[9]=0b10010000;
numbers[0]=0b11000000;
numbers[10]=0b10001000;
numbers[11]=0b10000011;
numbers[12]=0b11000110;
numbers[13]=0b10100001;
numbers[14]=0b10000110;
numbers[15]=0b10001110;
PORTA=0b00000000;
o[3]=0b00001111;
Note, I do not have a good track record with transistors.
I currently have the following path:
4x ( +5V C-> 2n3904 -> E), with the Base connected to a pin of the PIC directly. Mu understanding, is that taking the PIC pin high will cause the transistor to activate at full on, allowing whatever current wants to flow.
E is going to the common Anode on a digit (or the anodes of the separated status LEDs)
From the distinct cathodes on the digits/LEDs, these are joining, 4 at a time and going to an 180OHM resistor for each group of 4, and then onto a distinct PIC pin.

My 'concern' is I guess, it is possible that the ghosting could be a reverse current through the LED segments? There will be +5V at the cathode of a segment, but at the transistor end, there should be a float with almost infinite resistance? (As the C and B will be equal, it should also be like a diode in reverse).
 
Last edited:

bretm

Joined Feb 6, 2012
152
I currently have the following path:
4x ( +5V C-> 2n3904 -> E), with the Base connected to a pin of the PIC directly. Mu understanding, is that taking the PIC pin high will cause the transistor to activate at full on, allowing whatever current wants to flow.
This could be more current than the base-emitter junction can handle, and more than the PIC can supply without being damaged. You definitely need a base resistor.

It's also unusual to use NPN. This is a high-side switch, so the base-emitter voltage will decrease as the LED forward voltage increases. Ideally you'd use a PNP for a high-side switch, that way the base voltage just needs to be below the +5 rail, which isn't affected by the LED voltage. Then you just need to be to invert the PIC output feeding into the base.

NPN vs PNP doesn't explain ghosting, but damaged transistors or damaged PIC ports could.

My 'concern' is I guess, it is possible that the ghosting could be a reverse current through the LED segments?
They wouldn't light up if reverse-biased.
 

Thread Starter

coldpenguin

Joined Apr 18, 2010
165
It's also unusual to use NPN. This is a high-side switch, so the base-emitter voltage will decrease as the LED forward voltage increases. Ideally you'd use a PNP for a high-side switch, that way the base voltage just needs to be below the +5 rail, which isn't affected by the LED voltage. Then you just need to be to invert the PIC output feeding into the base.
oh a**e, you don't know how many weeks I have been debating which one to use.
Back to the drawing board!
 

bretm

Joined Feb 6, 2012
152
Also consider using P-channel MOSFET. That way you wouldn't need base resistors (the gate is super high impedance). It doesn't seem like switching speed will be a problem in your case. But PNPs seem easier to find than logic-level P-channel MOSFETs unless you're mail-ordering them anyway.
 
Top