Meh Belly Lint Collection

That awful moment when you realize,
THIS is YOUR circus and THOSE are YOUR monkeys.

User Tools

Site Tools


server_status_oled_display

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
server_status_oled_display [2025/03/23 00:20] kensonserver_status_oled_display [2026/05/06 04:56] (current) kenson
Line 2: Line 2:
 ===== Displayinator v1.0 ===== ===== Displayinator v1.0 =====
  
-This is a device you can shove into a spare USB connector on say a server rack system to display info like IP/Hostname/etc.+This is a device you can shove into a spare USB connector on say a server rack system to display info like IP/Hostname/etc. It has an accelerometer so it can determine orientation (for racks which have sideways USB) and a simple font compression selection so it can dynamically fit information on one line. 
 {{ :displayinator.jpg?direct&400 |}} {{ :displayinator.jpg?direct&400 |}}
  
-This is a old school project using a ATMEGA32U4.+This is a old school project using a ATMEGA32U4. Hindsight being 20/20 I should have chosen a more modern microcontroller as the 2.5K of RAM was a significant limitation requiring excessive use of PROGMEM in places you ordinarily wouldn't.
  
 +Notes:
   * The board is a clone of an Arduino Micro, and I2C is connnected to the OLED (SSD1315) and the Accelerometer (MMA8451).   * The board is a clone of an Arduino Micro, and I2C is connnected to the OLED (SSD1315) and the Accelerometer (MMA8451).
   * The OLED's I2C address 0x3C, and I'm using adafruit's 1306 driver, mainly for display rotation support.   * The OLED's I2C address 0x3C, and I'm using adafruit's 1306 driver, mainly for display rotation support.
   * The Accelerometer's address is 0x1C and the adafruit MMA8541 driver is basic but functional. Note that the more advanced features (e.g. tap to click) built into the chip are unavailable with this library.   * The Accelerometer's address is 0x1C and the adafruit MMA8541 driver is basic but functional. Note that the more advanced features (e.g. tap to click) built into the chip are unavailable with this library.
 +
 +
 +====== TLDR; ======
 +
 +
 +Probe the port.
 +
 +<code>
 +sudo tee ./probe_displayinator.py >/dev/null <<'EOF'
 +#!/usr/bin/env bash
 +set -u
 +
 +BAUD=115200
 +
 +for PORT in /dev/ttyUSB* /dev/ttyACM*; do
 +    [ -e "$PORT" ] || continue
 +
 +    echo "========================================"
 +    echo "Probing $PORT"
 +
 +    if ! stty -F "$PORT" "$BAUD" raw -echo -echoe -echok -echoctl -echoke 2>/dev/null; then
 +        echo "Could not configure $PORT"
 +        continue
 +    fi
 +
 +    # Some Arduino/32U4-style boards reset when serial opens
 +    sleep 4
 +
 +    # Wake / clear any stale output
 +    printf '\n' > "$PORT"
 +    sleep 0.2
 +    timeout 1 cat "$PORT" >/dev/null 2>&1
 +
 +    # Ask version
 +    printf '!VER\n' > "$PORT"
 +
 +    echo "Response from $PORT:"
 +    timeout 2 cat "$PORT" || true
 +    echo
 +done
 +EOF
 +chmod +x probe_displayinator.py
 +./probe_displayinator.py
 +</code>
 +
 +Download the agent: {{ :displayinatorhostip.zip |}}
 +<code>
 +wget 'https://mehngineering.com/wiki/lib/exe/fetch.php?media=displayinatorhostip.zip' -O displayinatorhostip.zip
 +unzip displayinatorhostip.zip
 +</code>
 +
 +Insert the service to autostart
 +<code>
 +sudo tee /etc/systemd/system/displayinator.service >/dev/null <<'EOF'
 +[Unit]
 +Description=Displayinator Host IP Sender
 +Wants=network-online.target
 +After=network-online.target multi-user.target
 +
 +[Service]
 +Type=oneshot
 +WorkingDirectory=/root
 +ExecStartPre=/bin/sleep 10
 +ExecStart=/usr/bin/python3 /root/DisplayinatorHostIP.py --port /dev/ttyACM0
 +StandardOutput=append:/var/log/displayinator-hostip.log
 +StandardError=append:/var/log/displayinator-hostip.log
 +
 +[Install]
 +WantedBy=multi-user.target
 +EOF
 +</code>
 +
 +Edit /etc/systemd/system/displayinator.service and change the port to whatever device the probe finds, usually /dev/ttyACM0 or /dev/ttyUSB0
 +<code>ExecStart=/usr/bin/python3 /root/DisplayinatorHostIP.py --port /dev/ttyACM0
 +</code>
 +
 +Start the service.
 +
 +<code>
 +systemctl daemon-reload
 +systemctl enable --now displayinator.service
 +systemctl status displayinator.service
 +</code>
  
 ==== Loading the Arduino Bootloader ==== ==== Loading the Arduino Bootloader ====
Line 18: Line 103:
  
 avrdude will complain about older firmware but my recommendation is to ignore it. avrdude will complain about older firmware but my recommendation is to ignore it.
-The TLDR; is the chinese firmware is modified and does some automagic stuff and in general works more reliably than the publicly available open source code version.+The [[USBasp flash|TLDR;]] is the chinese firmware is modified and does some automagic stuff and in general works more reliably than the publicly available open source code version.
  
 Use zadig to make it (USBasp) use libusb-win32 Use zadig to make it (USBasp) use libusb-win32
  
-Copy avrdude to the arduino avrdude location. (You can "Show verbose output during [X] compile [X] upload" in File->Preferences to try to upload to see where it is)+Copy avrdude v8 (The one that ships with arduino is v5 and doesn't work.) to the arduino avrdude location. (You can "Show verbose output during [X] compile [X] upload" in File->Preferences to try to upload to see where it is) 
  
 Then from Arduino, select USBasp in Tools->Programmer and burn using Tools->Burn Bootloader Then from Arduino, select USBasp in Tools->Programmer and burn using Tools->Burn Bootloader
Line 42: Line 127:
 I uses the accelerometer to detect orientation so it should be right side up. I uses the accelerometer to detect orientation so it should be right side up.
  
-The USB serial is nominally 115200, and the commands it takes are+The USB serial is nominally 115200
 + 
 +==== Command structure ==== 
 + 
 +The command protocol is simple:  
 +  * Commands are prepended with an '!' and terminated with a newline '\n'
 +  * Key-Value pairs are prepended with a '@'space ' ' delimited and terminated with a newline '\n' 
 +  * You can also indicate not to store values in EEPROM by putting a caret '^' after the @ symbol 
 + 
 +==== Commands ====
  
 !LIST which displays the stored key-value pairs !LIST which displays the stored key-value pairs
Line 75: Line 169:
 </code> </code>
  
-Everything else is checked to see if it is a Key-Value pair. pair is just two, space-delimited, alphanumeric wordsE.g.+ 
 +==== KEY VALUE STORAGE ==== 
 + 
 +If the line starts with a '@', it will indicate that we're passing in a Key Value pair. The Key-Value pair is space delimited.  
 + 
 +Note that this '@' symbol is not passed in 
 <code> <code>
-HAPPY GILMORE+@HAPPY GILMORE
 Space index found at: 5 Space index found at: 5
 Key extracted: 'HAPPY', Value extracted: 'GILMORE' Key extracted: 'HAPPY', Value extracted: 'GILMORE'
 Added HAPPY = GILMORE Added HAPPY = GILMORE
 +</code>
 +
 +Note only the first space is used as a delimiter, successive spaces are considered part of the Value.
 +
 +<code>
 +@KEY Value cow
 +KEY Value cow, Space @: 3
 +Key extracted: 'KEY', Value extracted: 'Value cow'
 +Added KEY = Value cow
 +</code>
 +
 +KV pairs are normally stored in flash and will be loaded on power on. Sometimes this behavior is undesired, for example rapidly changing information like CPU Load. In this case, a '^' is used to specify skipping permanent storage. Note that the caret is stored in the Key but not displayed.
 +
 +<code>
 +@^CPU 48%
 +^CPU 48%, Space @: 4
 +Key extracted: '^CPU', Value extracted: '48%'
 +Updated ^CPU = 48%
 </code> </code>
  
Line 90: Line 208:
   * It also likes to reset when you connect via serial so I wait 3 to 5 seconds for it to boot up before poking it.    * It also likes to reset when you connect via serial so I wait 3 to 5 seconds for it to boot up before poking it. 
   * Python raises DTR, and for whatever reason it breaks things, so I set ser.dtr = False.   * Python raises DTR, and for whatever reason it breaks things, so I set ser.dtr = False.
 +  * You never know whats in a serial buffer when you connect so send a '\n' and read the buffer to make sure everything is sane when you connect.
  
 ==== TrueNAS ===== ==== TrueNAS =====
server_status_oled_display.1742689205.txt.gz · Last modified: 2025/03/23 00:20 by kenson

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki