Making an IPAddress variable scrollable on a 7 segment display

Hello,

I have always had problems when displaying numbers that length varies.

I have a 4 digit 7 segment display with a NodeMCU. What I would like is to make the IP address scrollable on the 7 segment display. I don't have the option to declare the fixed ip address, and there comes the problem. The ip address length ranges from 8 - 12 digits. (192.168.0.0 - 192.168.255.255)

IPAddress ipa;
ipa = WiFi.localIP();
uint8_t one = ipa[0];  //this gives me the first part and so on
uint8_t two = ipa[1];
uint8_t three = ipa[2];
uint8_t four = ipa[3];

So I have the address in blocks.

I've tried several methods. As the first two is fixed (192 and 168), I counted the length of the third and the fourth part. They range from 1 to 3. This gave me 18 cases which would be a nightmare to code.

If I could somehow convert the ip address to a large integer (for example: 192168010), then I would only have to use 4 cases. (Length: 8 - 12) Also I would move the decimal point accordingly.

The scrolling is just done with for loops, and I used the LedControl library for the 7 segment.

Is it possible to achieve this?

Is it possible to achieve this?

Yes.

But, imho barely readable on a 4 digit display. You will see the numbers better if you just print the 4 octets one by one

Using a 8 digit display I print in two octets at once:

void writeIpOn7Segment() {
  lc.clearDisplay(0);
  lc.setCursor(0, 0);
  lc.print(F("IP "));
  lc.print(ip[0]);
  lc.print(F("."));
  lc.print(ip[1]);
  lc.print(F("."));
  delay(delaytime * 8);
  lc.clearDisplay(0);
  lc.setCursor(0, 0);
  lc.print(F("IP "));
  lc.print(ip[2]);
  lc.print(F("."));
  lc.print(ip[3]);
  delay(delaytime * 8);
}

I have always had problems when displaying numbers that length varies.

well, I guess you should consider a library which supports an easier print of numbers (and everything else). My variant of led control Arduino Noiasca LED Control with print method (MAX7219/MAX7221) enables the write/print like you are used from the serial interface.

Holy cow you made an awesome library! I tried some example code, and noticed that the numbers are reversed. (for example 123 prints 321) My wiring is perfect as the MAX7219 Digit 0 pin goes to digit 0 on the display. I might be wrong but I think it could be a software related thing.

SwengX: Hello,

I have always had problems when displaying numbers that length varies.

I have a 4 digit 7 segment display with a NodeMCU. What I would like is to make the IP address scrollable on the 7 segment display. I don't have the option to declare the fixed ip address, and there comes the problem. The ip address length ranges from 8 - 12 digits. (192.168.0.0 - 192.168.255.255)

Can you post the relevant part(s) of your code that drives the 7-seg displays? The whole code if possible; if it's too large or proprietary, just post a minimally viable but complete sketch that drives the 7-segs.

SwengX: I tried some example code, and noticed that the numbers are reversed. (for example 123 prints 321) My wiring is perfect as the MAX7219 Digit 0 pin goes to digit 0 on the display. I might be wrong but I think it could be a software related thing.

I'm mostly using these Chinese 8 digit modules and they work as planned. But if you provide a schematic of your display I will do a crosscheck. Also provide a short sketch writing "3210" on the display how you would do it with the original LedControl?

edit: As mentioned on my page, the original library uses "digit" - numbered from 7 to 0 (left to right)

digits: 7 6 5 4 3 2 1 0

so in your case you should have wired your digits to 3 2 1 0, where digit 0 is pin 2 and digit 3 is pin 7

Okay, so I have no option to rewire the display as it is on a pcb. But I found the line in the libary where it reverses the numbers

uint8_t digit = 7 - (currentPosition % 8); // invers because digits are in this order: 7 6 5 4 3 2 1 0

Would it help if I changed it to just only uint8_t digit = currentPosition % 8?

just try it and do a test. If it works - well done.

If you see nothing afterwards, test with lcd.print("01234567") -just in case you were using the last 4 digits...

Then test the dots. It might be that this line will also need a change:

uint8_t lastDigit = 7 - (lastPosition % 8);

Hmmm... Interesting. I tried it and it did reverse but the it got a bit messed up.

I tested 8 cases of the cursor.

I used lc.setCursor(0, n); and lc.print("01234567");

Here is what the output looks like:

|326x500

Maybe I should go negative with the cursor but that of course means I have to redo the math in the library. The first column is the cursor and the rest of them are the digits on the display.

is the first column the parameter of setCursor? and the other 4 colums are your display?

please post a schematic so we can see which pin/max-digit you have connected to which digit on your display.

and recap post #4. Provide a sketch showing “3210” on your display with the original library

|384x500

Yes, the first column of the table is the parameter of the setCursor, sorry if it was confusing. The first column is the cursor and the rest of them are the digits on the display.

This code shows exactly "3210" with my old method and the original LedControl library.

//We always have to include the library
#include "LedControl.h"

/*
  Now we need a LedControl to work with.
 ***** These pin numbers will probably not work with your hardware *****
  pin 12 is connected to the DataIn
  pin 11 is connected to the CLK
  pin 10 is connected to LOAD
  We have only a single MAX72XX.
*/
LedControl lc = LedControl(13, 14, 12, 1);
void setup() {
  /*
    The MAX72XX is in power-saving mode on startup,
    we have to do a wakeup call
  */
  lc.shutdown(0, false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0, 15);
  /* and clear the display */
  lc.clearDisplay(0);
}
void loop() {
  int value = 3210;
  byte digit1 = value / 1000;
  byte digit2 = (value / 100) % 10;
  byte digit3 = (value % 100) / 10;
  byte digit4 = value % 10;
  lc.setDigit(0, 0, digit1, false);
  lc.setDigit(0, 1, digit2, false);
  lc.setDigit(0, 2, digit3, false);
  lc.setDigit(0, 3, digit4, false);

}

I don’t see the wiring of the display.
D0 / the G1 digit is the left most digit?

edit: this could work.
Replace the write method in the respective .cpp:

//noiasca's virtual method to write (print, println) characters PATCHED FOR WRONG ORDER DISPLAYS
size_t LedControl::write(uint8_t value) {
  uint8_t addr = currentPosition / 8;
  //uint8_t digit = 7 - (currentPosition % 8); // invers because digits are in this order: 7 6 5 4 3 2 1 0
  uint8_t digit = (currentPosition % 8); // SWENGX
  //Serial.print("\ncurrentPosition:"); Serial.print(currentPosition);
  //Serial.print(" addr:"); Serial.print(addr);
  //Serial.print(" digit:"); Serial.print(digit);
  //Serial.print(" value:"); Serial.print(value); Serial.println();

  if (value == 10)                                            // \n linefeed
  {
    handleEndOfDevice(addr); 
  }
  else if (value == 13)                                       // \r carriage return MISSING: eventuell alles unter 32 nicht ausgeben
  {
    // don't print carriage return
  }  
  else if (value == '.' || value == ',')                    // MISSING: Prüfung auf digit < 7 ausgebaut
  {
    uint8_t lastAddr = lastPosition / 8;
    uint8_t lastDigit = lastPosition % 8; //SWENGX
    setRow(lastAddr, lastDigit, status[lastAddr * 8 + lastDigit] | 0b10000000);  //add decimal point to the last printed digit
    //setRow(addr, digit + 1, status[addr * 8 + digit + 1] | 0b10000000);        //add decimal point to the heading digit
  }
  else 
  {
    setChar(addr, digit, value, 0);
    lastPosition = currentPosition;
    currentPosition++;
    if (digit > 7) handleEndOfDevice(addr); // SWENGX
  }
  return 1; // assume sucess
}

This was my test-Sketch:

#include "NoiascaLedControl.h"       // We always have to include the library

/*
 Now we need a LedControl to work with.
 ***** These pin numbers will probably not work with your hardware *****
 We have only a single MAX72XX.
 */
const uint8_t LEDCS_PIN = 8;           // 8 LED CS or LOAD -  8 CS
const uint8_t LEDCLK_PIN = 7;          // 7 LED Clock      - 13 CLK on UNO/NANO
const uint8_t LEDDATA_PIN = 9;         // 9 LED DATA IN    - 11 MOSI on UNO/NANO
const uint8_t LED_MODULES = 2;     

LedControl lc = LedControl  (LEDDATA_PIN, LEDCLK_PIN, LEDCS_PIN, LED_MODULES);  // Software Bitbang - use this if you can't use Hardware SPI

void setup() {
  Serial.begin(115200);
  /*
    The MAX72XX is in power-saving mode on startup,
    we have to do a wakeup call
  */
  lc.shutdown(0, false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0, 15);
  /* and clear the display */
  lc.clearDisplay(0);

  //byNoiasca(); delay(2000);
  byFloat();
}
void loop() {
}

void byNoiasca()
{
  int value = 3210;
  lc.print(value);
}

void byFloat()
{
  float value = 32.10;
  lc.print(value);
}

void byHand()
{
  int value = 3210;
  byte digit1 = value / 1000;
  byte digit2 = (value / 100) % 10;
  byte digit3 = (value % 100) / 10;
  byte digit4 = value % 10;
  lc.setDigit(0, 0, digit1, false);
  lc.setDigit(0, 1, digit2, false);
  lc.setDigit(0, 2, digit3, false);
  lc.setDigit(0, 3, digit4, false); 
}

Yes. Here is the image from the datasheet.

ok, how does the code in #10 after the patch of the .cpp work for you?

Omg, it works! Playing with the cursor also works! Your test code works too. Thank you so much for the help! You made a very powerful library!

Good to hear! Then I have a proposal:

download again the library. I’ve updated the lib this afternoon. You will find a new example called “LCDemoNoiascaInversed.ino”. It will implement a class for inversed displays in the user sketch and includes this adopted write method. Just add the class at the beginning of your sketch and use the new class name when you create your lc object.

You don’t need to patch the library any more. And if you buy some day displays with the standard order, it will still work out of the shelf.

Yes, I saw the updates on your website. I downloaded the new version. Thanks again!