Jump to content

Need help with programing tm1637 6 digit 7 segment display


Hatiz

Recommended Posts

Hello! As the title says I need help with my segment display.

Im making uhf radio panel for my f-16c simpit. I bought that nice display https://pl.aliexpress.com/item/4001293690559.html?gatewayAdapt=glo2pol&spm=a2g0o.order_list.0.0.21ef1c24AJGZ6f

After many hours trying to make it work with DCS BIOS, it's actually worked... But there are some issues. 

When I turn on radio, digits turns on too and I can change them correctly, but when Im turning off radio, all digits are changing to 0 and staying in that position til I turn radio on again. I want to have blank display!

My code:

/* Mega and Uno pinout is the same
*  GRND = GRND
*  VCC = 5V
*  D10 = Digital input pin - this code uses pin 3
*  CLK = Digital input pin - this code uses pin 2
*/
#define DCSBIOS_DEFAULT_SERIAL

#include <Arduino.h>

#include <TM1637TinyDisplay6.h>

#define CLK 2 //pins definitions for TM1637 and can be changed to other ports
#define DIO 3

TM1637TinyDisplay6 display(CLK, DIO);

#include "DcsBios.h"

uint8_t data[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };    // Test Pattern - All
uint8_t blank[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };   // Test Pattern - Blank
uint8_t dots = 0b01010000; // Add dots or colons (depends on display module)

// DCS-Bios Code

void onUhfFreqDispChange(char* newValue) { 
                                                //newValue[3] - dot
    display.setBrightness(1);
    data[0] = display.encodeDigit(newValue[0]); // digit 1
    data[1] = display.encodeDigit(newValue[1]); // digit 2
    data[2] = display.encodeDigit(newValue[2]); // digit 3
    data[3] = display.encodeDigit(newValue[4]); // digit 4
    data[4] = display.encodeDigit(newValue[5]); // digit 5
    data[5] = display.encodeDigit(newValue[6]); // digit 6
    display.setSegments(data);
}
DcsBios::StringBuffer<7> uhfFreqDispBuffer(0x4590, onUhfFreqDispChange);

// End DCS-Bios Code

void setup()
 {
  DcsBios::setup();
  display.clear();
  display.setSegments(blank);
}

void loop()
 {
   DcsBios::loop();
 }

Library that I'm using: https://github.com/jasonacox/TM1637TinyDisplay I was trying many others but that one seems to work the best for me.

I'm using arduino mega

Thank you in advance for help and sorry for my English!

Link to comment
Share on other sites

I would check if the radio is off and than "clear" the display or set brightness to zero.

Regards, Vinc

Edit: If there is a mode switch on the radio, the output of it's "off" position could be used for the above check.


Edited by Vinc_Vega

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

On 2/20/2022 at 8:22 PM, Vinc_Vega said:

I would check if the radio is off and than "clear" the display or set brightness to zero.

Regards, Vinc

Edit: If there is a mode switch on the radio, the output of it's "off" position could be used for the above check.

 

Yes but e.g if I lose power it still be working and displaying zeros until I turn off radio. it's doesn't depend from dcs bios, but from physical switch. I'm not satisfied with that solution 😕

Link to comment
Share on other sites

He is already looking into a string. But than the digits from that string were extracted for each single display.

Try the showString or showNumber commands.

 

Regards, Vinc


Edited by Vinc_Vega

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

22 hours ago, No1sonuk said:

Can you not just send the string to the display?

https://forum.arduino.cc/t/tm1637-6-digit-led-display/702875

I do that with a character LCD, and the string is spaces when the radio is off.

 

9 hours ago, Vinc_Vega said:

He is already looking into a string. But than the digits from that string were extracted for each single display.

Try the showString or showNumber commands.

 

Regards, Vinc

 

I tried showString and it's making blank display while radio is off, but its showing dot in digit place so value is too long to fit in display and because of that it is scrolling and disappear.

void onUhfFreqDispChange(char* newValue) {

  display.setBrightness(BRIGHT_HIGH);
  display.showString(newValue);
} 
DcsBios::StringBuffer<7> uhfFreqDispBuffer(0x4590, onUhfFreqDispChange);

How to set dot correctly in right place? Or how to remove dot?

I know that I can isolate value like newValue[3] (dot), but I don't know what to do with this fact.

Link to comment
Share on other sites

Okay, that's because the string has seven members (chars), six digits plus the separate space.

Try to read out the positions in the string [0] to [2] and [4] to [6] and print that to the respective displays. Than set your colon after the third digit.

Have a look at the examples (TM1637-6Digit-Test.ino) from line 192 on.

Regards, Vinc


Edited by Vinc_Vega

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

Can you convert the 7 character string to 6, then send the point separately?
e.g. the "remove" function:
https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/remove/

OR maybe convert it to a float then send that:
https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/tofloat/


Edited by No1sonuk
Added tofloat
Link to comment
Share on other sites

19 hours ago, No1sonuk said:

Can you convert the 7 character string to 6, then send the point separately?
e.g. the "remove" function:
https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/remove/

OR maybe convert it to a float then send that:
https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/tofloat/

 

I deleted dot from value and now have 6 characters so it should fit perfectly in display, but it keep scrolling.

void onUhfFreqDispChange(char* newValue) {
  
  char str[6] = {(newValue[0]), (newValue[1]), (newValue[2]), (newValue[4]), (newValue[5]), (newValue[6])};

  display.setBrightness(BRIGHT_HIGH);
  display.showString(str);
} 
DcsBios::StringBuffer<7> uhfFreqDispBuffer(0x4590, onUhfFreqDispChange);

I made that different than you told me, but with the same results (6 characters).

Link to comment
Share on other sites

20 hours ago, No1sonuk said:

Try changing "display.showString(str);" to:

display.showString(str,6,0,0b00100000);

I don't have a display to test it, but from the library documentation, that should display only 6 characters, starting at 0 (full left), and place the DP in the middle.

Still scrolling, Im losing my mind...

Edit: String still must thinking that is to long and that's why is skipping characters. But why if theres is 6 characters?
When Im trying display uhf chan which is 2 characters its working perfectly with no problems.

12.PNG


Edited by Hatiz
Link to comment
Share on other sites

3 hours ago, Hatiz said:

Still scrolling, Im losing my mind...

Edit: String still must thinking that is to long and that's why is skipping characters. But why if theres is 6 characters?
When Im trying display uhf chan which is 2 characters its working perfectly with no problems.

12.PNG

 

Have a look in the documentation and see how the function works:

Spoiler
  //! Display a string
  //!
  //! Display the given string and if more than 4 characters, will scroll message on display
  //!
  //! @param s The string to be shown
  //! @param scrollDelay  The delay, in microseconds to wait before scrolling to next frame
  //! @param length The number of digits to set. 
  //! @param pos The position of the most significant digit (0 - leftmost, 3 - rightmost)
  //! @param dots Dot/Colon enable. The argument is a bitmask, with each bit corresponding to a dot
  //!        between the digits (or colon mark, as implemented by each module). i.e.
  //!        For displays with dots between each digit:
  //!        * 00.0000  (0b01000000)
  //!        * 0.00000  (0b10000000)
  //!        * 00.0000  (0b01000000)
  //!        * 000.000  (0b00100000)
  //!        * 0000.00  (0b00010000)
  //!        * 00000.0  (0b00001000)
  //!        * 000000.  (0b00000100)
  //!        * 00.00.00 (0b01010000)
  //!        For displays with just a colons:
  //!        * 00:00:00 (0b01010000)  
  //! Use showString_P function for reading PROGMEM read-only flash memory space instead of RAM
  void showString(const char s[], uint8_t length = MAXDIGITS, uint8_t pos = 0, uint8_t dots = 0);

 

That means to me, all strings larger than 4 characters will scroll your display.

I propose to split the string into two strings of 3 characters to be send to the respective display groups (digit 1 to 3 and 4 to 6).

Try it out and post your results here!

Regards, Vinc


Edited by Vinc_Vega

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

As I wrote above, it's documented in the TM1637 library that strings with more than 4 characters will scroll.

According to the data sheet the TM is very different to the Max chip.

If scrolling could be avoided indeed the authors should talk to each other 😉

Regards, Vinc


Edited by Vinc_Vega

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

18 hours ago, Vinc_Vega said:

Have a look in the documentation and see how the function works:

  Ukryj zawartość

 

Oznacza to dla mnie, że wszystkie ciągi większe niż 4 znaki będą przewijać Twój wyświetlacz.

Proponuję podzielić ciąg na dwa ciągi po 3 znaki, które zostaną wysłane do odpowiednich grup wyświetlaczy (cyfry od 1 do 3 i od 4 do 6).

Wypróbuj i opublikuj swoje wyniki tutaj!

Pozdrawiam, Vinc

 

void onUhfFreqDispChange(char* newValue) {

  display.setBrightness(2);
  char str1[3] = {(newValue[0]), (newValue[1]), (newValue[2])};
  display.showString(str1,3,0);
} 
DcsBios::StringBuffer<7> uhfFreqDispBuffer(0x45a8, onUhfFreqDispChange);

keep scrolling even when char str1[1] = {(newValue[0])};

It's really strange...

Link to comment
Share on other sites

OK.
I've had a look at the library code itself.
There's apparently no optional parameter to stop scrolling when the string is longer than the MAXDIGITS parameter in the library.
MAXDIGITS is defined as 6 in the library, and it might be misreading the string as being longer than 6 digits.
Hopefully, adding a definition of MAXDIGITS  again after the library will counteract that.

Try changing:

#include <TM1637TinyDisplay6.h>

into:

#include <TM1637TinyDisplay6.h>
#define MAXDIGITS           7

Link to comment
Share on other sites

27 minutes ago, No1sonuk said:

OK.
I've had a look at the library code itself.
There's apparently no optional parameter to stop scrolling when the string is longer than the MAXDIGITS parameter in the library.
MAXDIGITS is defined as 6 in the library, and it might be misreading the string as being longer than 6 digits.
Hopefully, adding a definition of MAXDIGITS  again after the library will counteract that.

Try changing:

#include <TM1637TinyDisplay6.h>

into:

#include <TM1637TinyDisplay6.h>
#define MAXDIGITS           7

Didn't help

Link to comment
Share on other sites

OK.
Add this:

void showString_new(const char s[], uint8_t length, uint8_t pos, uint8_t dots)
{
  // digits[MAXDIGITS] output array to render
  memset(digits,0,sizeof(digits));

  // Basic Display
  if (strlen(s) <= MAXDIGITS) {
    for (int x = 0; x < strlen(s); x++) {
      digits[x] = encodeASCII(s[x]);
    }
    if(dots != 0) {
      display.showDots(dots, digits);
    }
    display.setSegments(digits, length, pos);
  }
}

And instead of "display.showString", use "showString_new" with all the same parameters.
That code is from the library's showString function, but with the scrolling part removed.


Edited by No1sonuk
Missed "display." calls
Link to comment
Share on other sites

  • 4 weeks later...

It took a while to get those cheap displays from China.

I confirm the problem of the rolling numbers and unfortunately the above proposed function "showString_new" is not working.

Here is a sketch to display the UHF radio frequency of the A-10C on a LED display of the TM1637 type.

Like requested above, the display is blanked while the switch is in the OFF position or no electrical power is supplied.

If "GRD" is choosen for the Frequency Mode Dial the 243.000 MHz are displayed, but proper display of pre-programmed frequencies (presets) still have to be checked.

As all LED displays only have seven segments, the number 888.888 will be shown in test mode (***.***).

Feel free to use the sketch or parts of it!

Edit: the display can be dimmed by the LCP SignalLights switch  😉

Spoiler
/* use '#define DCSBIOS_DEFAULT_SERIAL' instead if your Arduino board
   does not feature an ATMega328 or ATMega2650 controller. */

#define DCSBIOS_IRQ_SERIAL
#include "DcsBios.h"

#include <Arduino.h>
#include <TM1637TinyDisplay6.h>

// ---------- Code for the DCS: A-10C UHF Radio panel ----------

// still to be confirmed/checked: proper display of pre programmed frequencies (presets)

// Module connection pins (Digital Pins)
#define CLK 4
#define DIO 5

// Create the display object
TM1637TinyDisplay6 display(CLK, DIO);

// ---------- DCS-BIOS stuff ----------

// variables for he UHF display
String uhf_display = "251.000"; // temp frequency for startup (everything greater than 1)
char* Uhf100mhzSel = "2"; // Frequency selectors
int Uhf10mhzSel = 5;
long Uhf1mhzSel = 1;
int UhfPoint1mhzSel = 0;
char* UhfPoint25Sel = "00";
int uhf_dial = 1; // UHF Function Dial OFF/MAIN/BOTH/ADF (preset: MAIN)
int UhfMode = 0;  // Frequency Mode Dial MNL/PRESET/GRD (preset: MNL)
byte  led_intensity = 5;  // control display intensity by the LCP_SIGNAL_LIGHTS switch (BRT / DIM)
byte  led_intensity_dimm = 0;

// read UHF frequency from selectors
void onUhf100mhzSelChange(char* newValue) {
    Uhf100mhzSel = newValue;
}
DcsBios::StringBuffer<1> uhf100mhzSelBuffer(0x1178, onUhf100mhzSelChange);

void onUhf10mhzSelChange(unsigned int newValue) {
    Uhf10mhzSel = newValue;
}
DcsBios::IntegerBuffer uhf10mhzSelBuffer(0x1170, 0x3c00, 10, onUhf10mhzSelChange);

void onUhf1mhzSelChange(unsigned int newValue) {
    Uhf1mhzSel = newValue;
}
DcsBios::IntegerBuffer uhf1mhzSelBuffer(0x1178, 0x0f00, 8, onUhf1mhzSelChange);

void onUhfPoint1mhzSelChange(unsigned int newValue) {
    UhfPoint1mhzSel = newValue;
}
DcsBios::IntegerBuffer uhfPoint1mhzSelBuffer(0x1178, 0xf000, 12, onUhfPoint1mhzSelChange);

void onUhfPoint25SelChange(char* newValue) {
  UhfPoint25Sel = newValue;
}
DcsBios::StringBuffer<2> uhfPoint25SelBuffer(0x117a, onUhfPoint25SelChange);

// read the shown frequency of the (main panel) display
void onUhfFrequencyChange(char* newValue) {
    uhf_display = newValue;
}
DcsBios::StringBuffer<7> uhfFrequencyBuffer(0x1180, onUhfFrequencyChange);

// read UHF Function Dial OFF/MAIN/BOTH/ADF
void onUhfFunctionChange(unsigned int newValue) {
    uhf_dial = newValue;
}
DcsBios::IntegerBuffer uhfFunctionBuffer(0x117c, 0x000c, 2, onUhfFunctionChange);

// read Frequency Mode Dial MNL/PRESET/GRD
void onUhfModeChange(unsigned int newValue) {
    UhfMode = newValue;
}
DcsBios::IntegerBuffer uhfModeBuffer(0x117c, 0x0003, 0, onUhfModeChange);

// Dimm Displays according to Signal Lights on the Light System Control Panel
void onLcpSignalLightsChange(unsigned int newValue) {
    switch (newValue)
    {
    case 0:
      display.setBrightness(led_intensity_dimm);
    break;      
    case 1:
      display.setBrightness(led_intensity);
    break;
    }
}
DcsBios::IntegerBuffer lcpSignalLightsBuffer(0x1144, 0x0200, 9, onLcpSignalLightsChange);

// ---------- End of DCS-BIOS stuff ----------

// ---------- Beginn of SETUP section ----------
void setup()
{
  DcsBios::setup();
  
// animated test sequence
  display.setBrightness(led_intensity);
  display.showString(" A-10C");
  delay(2500);
  display.showString("U H F");
  delay(1500);
  display.clear();
  
} // ---------- End of SETUP section ----------


// ---------- Begin of the LOOP section ----------
void loop() {

  DcsBios::loop();

// UHF frquency TM1637 LED display
if ((uhf_display >= "1") && (uhf_display != "***.***"))
  {
  switch (UhfMode)
    {
      case 2: 
        display.showNumber(243.000);
        break;
      default:
        showFrequency();
    }
  }
if ((uhf_display <= "1") && (uhf_display == "***.***")) // show "888.888" on display instead of "***.***"
  {
    display.showNumber(888.888);
  }
if ((uhf_display <= "1") && (uhf_display != "***.***")) // blank displays when UHF Mode is set to OFF or electr. power is removed
  {
    display.clear();
  }
// End of UHF frquency TM1637 LED display 
 
} // ---------- End of LOOP section ----------


// ---------- Declaration of functions ----------
void showFrequency()
{
    display.showString(Uhf100mhzSel, 1, 0, 0);
    display.showNumber(Uhf10mhzSel, false, 1, 1);  
    display.showNumberDec(Uhf1mhzSel, 0b10000000, false, 1, 2);
    display.showNumber(UhfPoint1mhzSel, false, 1, 3);
    display.showString(UhfPoint25Sel, 2, 4, 0); 
}

 

Regards, Vinc


Edited by Vinc_Vega

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

I've reworked the above sketch to work with the A-10C UHF string output only (and not the selectors).

Now it shows correctly all frequencies, including guard frequency and presets and the test mode.

If the UHF radio is not electrical powered, e.g. switched to OFF or BATT and generators are OFF, the displays are blanked.

LED brightness can be dimmed by the LCP Signal Lights switch, variables are adjustable (default: led_intensity = 5).

 

Edit:  To show preset UHF frequencies, push the status button when in PRE mode . Than you can see the selected preset a while.

 

Regards, Vinc

 

Spoiler
/* use '#define DCSBIOS_DEFAULT_SERIAL' instead if your Arduino board
   does not feature an ATMega328 or ATMega2650 controller. */

#define DCSBIOS_IRQ_SERIAL
#include "DcsBios.h"

#include <Arduino.h>

// ---------- Code for the DCS: A-10C UHF Radio panel ----------
#include <TM1637TinyDisplay6.h>
#define CLK 4// Module connection pins (Digital Pins)
#define DIO 5
TM1637TinyDisplay6 display(CLK, DIO);// Create the display object

// ---------- DCS-BIOS stuff ----------
// variables for he UHF display
String uhfFrequency = "251.000"; // temp frequency for startup
uint8_t data[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
byte  led_intensity = 5;  // dimm intensity by the LCP_SIGNAL_LIGHTS switch (BRT / DIM)
byte  led_intensity_dimm = 0;

// read the shown frequency of the display
void onUhfFrequencyChange(char* newValue) {
    uhfFrequency = newValue;
}
DcsBios::StringBuffer<7> uhfFrequencyBuffer(0x1180, onUhfFrequencyChange);

// dimm Displays according to Signal Lights on the Light System Control Panel
void onLcpSignalLightsChange(unsigned int newValue) {
    switch (newValue)
    {
    case 0:
      display.setBrightness(led_intensity_dimm);
    break;      
    default:
      display.setBrightness(led_intensity);
    break;
    }
}
DcsBios::IntegerBuffer lcpSignalLightsBuffer(0x1144, 0x0200, 9, onLcpSignalLightsChange);
// ---------- End of DCS-BIOS stuff ----------

// ---------- Beginn of SETUP section ----------
void setup()
{
DcsBios::setup();
  // startup sequence
  display.setBrightness(led_intensity);
  display.showString(" A-10C");
  delay(2500);
  display.clear();
} // ---------- End of SETUP section ----------

// ---------- Begin of the LOOP section ----------
void loop() {
DcsBios::loop();
  // UHF frquency TM1637 LED display
  if ((uhfFrequency >= "1") && (uhfFrequency != "***.***")) // display is ON and not in test mode (normal condition)
    {
     show_UhfFrequency();
    }
  if ((uhfFrequency <= "1") && (uhfFrequency == "***.***")) // display is OFF but in test mode "***.***"
    {
     display.showNumber(888.888);
    }
  if ((uhfFrequency <= "1") && (uhfFrequency != "***.***")) // display is OFF and not in test mode
    {                                                       // blank display when UHF Mode is set to OFF or electr. power is removed
     display.clear();
    }
} // ---------- End of LOOP section ----------

// ---------- Declaration of functions ----------
void show_UhfFrequency()
{
  // convert freq string to display the colon after the third digit
  data[0] = display.encodeASCII(uhfFrequency[0]); //  use a char to display "2", "3", or "A"
  int digit2 = String(uhfFrequency[1]).toInt(); // convert the rest of the string into separate integers
  int digit3 = String(uhfFrequency[2]).toInt();
  int digit4 = String(uhfFrequency[4]).toInt();
  int digit5 = String(uhfFrequency[5]).toInt();
  int digit6 = String(uhfFrequency[6]).toInt();
  
  // display the above variables
  display.setSegments(data, 1, 0);  //  digit1
  display.showNumber(digit2, false, 1, 1);  // digit2
  display.showNumberDec(digit3, 0b10000000, false, 1, 2);  // digit3 with decimal point
  display.showNumber(digit4, false, 1, 3);  // digit4
  display.showNumber(digit5, false, 1, 4);  // digit5
  display.showNumber(digit6, false, 1, 5);  // digit6
}

 

 


Edited by Vinc_Vega

Regards, Vinc

real life: Royal Bavarian Airforce

online: VJS-GermanKnights.de

[sIGPIC][/sIGPIC]

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...