By the way, my approach here would be to go back to basics. Create your own single IO pin example that turns segments on the LED on and off, make sure you can achieve that, then move forward and add a second/third/etc IO pin and control them all. This helps you prove IO is working as you expect, and that the 7-seg display works as you expect.
Then look at the way the example project drives the LEDs and see if it matches what your hardware needs - if not, change it.
Plus, if you dive into the code, you can see it turns off all the digits in order and then turns on only one (pickDigt() ) which can give the effect of a display that is not fully on or off but flickers… that’s probably all you’re seeing.
so let me ask, does it now work? Does it update correctly when you increment a counter or do whatever other test you have? And if so, is there anything else you need help with ?
The display is multiplexed so you will need to be able to refresh it very quickly to avoid flickering. Somewhere around every 10ms should be good enough.
I don’t think this is possible with NETMF as timing is not granular. This is why you are seeing flashing.
You need to disable the digit, write the new bit sequence and then able the digit. You seem to be enabling the digit first. Do this after you write the new sequence to it.
Repeat this for each one in turn as fast as you can and it may work.
public sealed class LM7SegDirect
{
private bool _isAnode;
private byte qtyDigits = 1;
private ThreadPoolTimer timer = null;
private GpioPin[] pins = new GpioPin[8];
private GpioPin[] digits = new GpioPin[4];
private GpioController gpio;
//--------
// Define each valid number configuration to show in the display
private byte[,] seven_seg_digits = new byte[10, 7]
{
{ 0,0,0,0,0,0,1 }, // = 0
{ 1,0,0,1,1,1,1 }, // = 1
{ 0,0,1,0,0,1,0 }, // = 2
{ 0,0,0,0,1,1,0 }, // = 3
{ 1,0,0,1,1,0,0 }, // = 4
{ 0,1,0,0,1,0,0 }, // = 5
{ 0,1,0,0,0,0,0 }, // = 6
{ 0,0,0,1,1,1,1 }, // = 7
{ 0,0,0,0,0,0,0 }, // = 8
{ 0,0,0,1,1,0,0 } // = 9
};
public int CurrentValue { get; set; }
public LM7SegDirect(byte segA, byte segB, byte segC, byte segD, byte segE, byte segF, byte segG, byte segDotn, bool isAnode)
{
byte[] pin_order = new byte[8];
_isAnode = isAnode;
pin_order[0] = segA;
pin_order[1] = segB;
pin_order[2] = segC;
pin_order[3] = segD;
pin_order[4] = segE;
pin_order[5] = segF;
pin_order[6] = segG;
pin_order[7] = segDotn;
gpio = GpioController.GetDefault();
// Show an error if there is no GPIO controller
if (gpio == null)
{
//@ @
}
//----------------
// Open each pin and turn the light of for it
for (int i = 0; i < 8; i++)
{
pins[i] = gpio.OpenPin(pin_order[i]);
pins[i].Write(GpioPinValue.Low);
pins[i].SetDriveMode(GpioPinDriveMode.Output);
}
//----------
// Create a timer that redraw the currentvalue each second
// OBS: If you want to change numbers faster than that, just fix the timespan for this timer
timer = ThreadPoolTimer.CreatePeriodicTimer(Timer_Tick, TimeSpan.FromMilliseconds(1));
}
//-----------------------------
// defineDigits
// Define how many digits the 7-segment have and what are the pin numbers
public void defineDigits(byte digitsQty, byte dig1, byte dig2, byte dig3, byte dig4)
{
byte[] digit_order = new byte[4];
qtyDigits = digitsQty;
digit_order[0] = dig1;
digit_order[1] = dig2;
digit_order[2] = dig3;
digit_order[3] = dig4;
//----------------
// Open each digit and turn the light of for it
for (int i = 0; i < digitsQty; i++)
{
digits[i] = gpio.OpenPin(digit_order[i]);
digits[i].Write(GpioPinValue.High);
digits[i].SetDriveMode(GpioPinDriveMode.Output);
}
}
//---------------------------------------------------------------------
// Write one number to a specific digit in the 7-Segment led
public void digitWrite(byte digit, int number)
{
try {
// If the desired digit does not exist, return
if (digit > qtyDigits)
return;
// Activate each led in the digit
int pinseq = 0;
for (byte segCount = 0; segCount < 7; ++segCount)
{
byte finalValue = seven_seg_digits[number, segCount];
if (!_isAnode)
finalValue = finalValue == (byte)1 ? (byte)0 : (byte)1;
pins[pinseq].Write(finalValue == 0 ? GpioPinValue.Low : GpioPinValue.High);
pinseq++;
}
// Here I am always turning off the DOT, because I dont want it
pins[pinseq].Write(_isAnode ? GpioPinValue.High : GpioPinValue.Low);
// Activate the digit
pickDigit(digit);
} catch(Exception e)
{
int c = 1;
}
}
//---------------------------------------------------------------------
// Dump the CurrentValue to the display.
// Up to 4 digits
public void valueWrite(int number)
{
CurrentValue = number;
if (timer == null)
timer = ThreadPoolTimer.CreatePeriodicTimer(Timer_Tick, TimeSpan.FromMilliseconds(500));
}
//--------------
// Each timer interval redraw the number in the display
private void Timer_Tick(ThreadPoolTimer timer)
{
if (CurrentValue < 10)
{
digitWrite(4, 0);
digitWrite(3, 0);
digitWrite(2, 0);
digitWrite(1, CurrentValue);
}
else if (CurrentValue < 100)
{
digitWrite(4, 0);
digitWrite(3, 0);
digitWrite(2, CurrentValue / 10);
digitWrite(1, CurrentValue % 10);
}
else if (CurrentValue < 1000)
{
digitWrite(4, 0);
digitWrite(3, CurrentValue / 100);
digitWrite(2, (CurrentValue % 100) / 10);
digitWrite(1, CurrentValue % 10);
}
else
{
digitWrite(4, CurrentValue / 1000);
digitWrite(3, (CurrentValue % 1000) / 100);
digitWrite(2, (CurrentValue % 100) / 10);
digitWrite(1, CurrentValue % 10);
}
}
//---------------------------------------------------------------------
// Activate a specific digit in the 7-Segment.
private void pickDigit(int x)
{
// If only one digit (7-Segment 1 Digit) then no need to continue here
if (qtyDigits == 1)
return;
// Turn off ALL digits
try {
for (int i = 0; i < qtyDigits; i++)
{
digits[i].Write(_isAnode ? GpioPinValue.Low : GpioPinValue.High);
}
// Turn ON only the desired digit
digits[x - 1].Write(_isAnode ? GpioPinValue.High : GpioPinValue.Low);
} catch (Exception e)
{
int c = 0;
}
}
}
I see again after going over your code again that it LED is common ANODE
You need to create a thread or some other method to continually refresh the LED displays. You can’t simply do this once per second as your timer is now. You have to redraw each one over and over to give the impression of a solid display. Remember you are multiplexing the 7 segments with each anode controlling which one is going to be switched on.
Create an array that holds the value to be displayed or some other way to record it. In the thread do your digits for each one. Don’t worry about the COUNT of digits, just update them all and have some value that indicates a digit is blank. 0x0A is a good one.
Put your thread to sleep for 10ms and see how that goes.