Skip to content

Instantly share code, notes, and snippets.

@mohitbhoite
Last active April 20, 2025 21:59
Show Gist options
  • Select an option

  • Save mohitbhoite/9ef05cf86a1761a5065c83b34404c659 to your computer and use it in GitHub Desktop.

Select an option

Save mohitbhoite/9ef05cf86a1761a5065c83b34404c659 to your computer and use it in GitHub Desktop.

Revisions

  1. mohitbhoite revised this gist May 6, 2023. 1 changed file with 4 additions and 3 deletions.
    7 changes: 4 additions & 3 deletions attiny85-satellite-lcd.cpp
    Original file line number Diff line number Diff line change
    @@ -2,8 +2,8 @@
    // Project link: https://www.bhoite.com/sculptures/satellite-2202/
    //
    #include "Adafruit_SHT31.h"
    #include <TinyWireM.h>
    #include <USI_TWI_Master.h>
    //#include <TinyWireM.h>
    //#include <USI_TWI_Master.h>
    #include <avr/sleep.h> //Needed for sleep_mode
    #include <avr/wdt.h> //Needed to enable/disable watch dog timer
    //Following is the header file for the LCD module bought on ebay
    @@ -29,7 +29,8 @@ void setup()
    pinMode(1, INPUT_PULLUP);
    ADCSRA &= ~(1<<ADEN); //Disable ADC, saves ~230uA
    // put your setup code here, to run once:
    TinyWireM.begin();
    //TinyWireM.begin();
    Wire.begin();
    sht31.begin(0x44);
    LCD.Init();
    LCD.DispStr("sat6");
  2. mohitbhoite revised this gist Apr 16, 2023. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions attiny85-satellite-lcd.cpp
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,6 @@
    //
    // Project link: https://www.bhoite.com/sculptures/satellite-2202/
    //
    #include "Adafruit_SHT31.h"
    #include <TinyWireM.h>
    #include <USI_TWI_Master.h>
  3. mohitbhoite revised this gist Apr 16, 2023. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions attiny85-satellite-lcd.cpp
    Original file line number Diff line number Diff line change
    @@ -51,6 +51,7 @@ void loop()
    int humidity = sht31.readHumidity();
    if (displayToggle)
    {
    //insure that the temperature is in a valid range
    if ((temperature <110) && (temperature > -20))
    {
    sprintf(data,"%doF",temperature);
    @@ -60,8 +61,8 @@ void loop()

    else
    {
    //insure that the temperature is in a valid range
    if ((temperature <101) && (temperature > 0))
    //insure that the humidity is in a valid range
    if ((humidity <101) && (humidity > 0))
    {
    sprintf(data,"%drH",humidity);
    LCD.DispStr(data);
  4. mohitbhoite revised this gist Apr 16, 2023. 3 changed files with 301 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions attiny85-satellite-lcd.cpp
    Original file line number Diff line number Diff line change
    @@ -3,6 +3,9 @@
    #include <USI_TWI_Master.h>
    #include <avr/sleep.h> //Needed for sleep_mode
    #include <avr/wdt.h> //Needed to enable/disable watch dog timer
    //Following is the header file for the LCD module bought on ebay
    //Seller link https://www.ebay.com/itm/284843842249
    //Information on the LCD http://www.hexpertsystems.com/LCD/
    #include <cdm4101.h>

    int ctr=1000;
    @@ -42,10 +45,6 @@ void loop()
    {
    setup_watchdog(9); //Setup watchdog to go off after 8sec
    sleep_mode(); //Go to sleep! Wake up 8 sec later
    //BME280setup();
    //temperature = ((BME280temperature()/100)*1.8)+32;
    //BME280sleep();


    int temperature = (sht31.readTemperature()*1.8)+32;
    //int temperature = sht31.readTemperature();
    @@ -61,6 +60,7 @@ void loop()

    else
    {
    //insure that the temperature is in a valid range
    if ((temperature <101) && (temperature > 0))
    {
    sprintf(data,"%drH",humidity);
    257 changes: 257 additions & 0 deletions cdm4101.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,257 @@
    //----------------------------------------------------------------------------

    #include <stdio.h>
    #include <string.h>
    #include <inttypes.h>
    #include "Arduino.h"

    #include "Wire.h"

    #include "cdm4101.h"

    //----------------------------------------------------------------------------

    #define I2C_ADDR (0x38)

    #define CMD_MODE_SET 0xCD
    #define CMD_LOAD_DP 0x80
    #define CMD_DEVICE_SEL 0xE0
    #define CMD_BANK_SEL 0xF8
    #define CMD_NOBLINK 0x70
    #define CMD_BLINK 0x71

    #define DASH 10
    #define UNDERSCORE 11
    #define SPACE 12
    #define ASTERISK 39
    #define ALPHA_START 13

    #define HOLD_TIME 8

    //----------------------------------------------------------------------------

    static byte const Segs[] =
    {
    0x6F, // 0x30 0
    0x03, // 0x31 1
    0x5D, // 0x32 2
    0x57, // 0x33 3
    0x33, // 0x34 4
    0x76, // 0x35 5
    0x7E, // 0x36 6
    0x43, // 0x37 7
    0x7F, // 0x38 8
    0x77, // 0x39 9
    0x10, // -
    0x04, // _
    0x00, // space
    0x7B, // A
    0x3E, // b
    0x6C, // C
    0x1F, // d
    0x7C, // E
    0x78, // F
    0x77, // G
    0x3B, // H
    0x02, // i
    0x0F, // J
    0x38, // K - can't do
    0x2C, // L
    0x5A, // M - can't do
    0x1A, // n
    0x6F, // O
    0x79, // P
    0x75, // Q - can't do
    0x18, // r
    0x76, // S
    0x3C, // t
    0x0E, // u
    0x2F, // V - can't do
    0x4E, // W - can't do
    0x2B, // X - can't do
    0x37, // y
    0x5D, // Z
    0x71, // ° - use * to represent it in your string
    };

    //----------------------------------------------------------------------------

    void CDM4101::Update(void)
    {
    byte data[5]; // bytes to send display segments

    if(Ctr)
    {
    Ctr--;
    return;
    }

    Wire.beginTransmission(I2C_ADDR);
    Wire.write(CMD_MODE_SET);
    Wire.write(CMD_LOAD_DP);
    Wire.write(CMD_DEVICE_SEL);
    Wire.write(CMD_BANK_SEL);


    if(Blink) Wire.write(CMD_BLINK);
    else Wire.write(CMD_NOBLINK);

    #if 1
    data[0] = (Digits[0] >> 4); // || LCD_BAR
    data[1] = (Digits[0] << 4) | (Digits[1] >> 3);
    data[2] = (Digits[1] << 5) | (Digits[2] >> 2);
    data[3] = (Digits[2] << 6) | (Digits[3] >> 1);
    data[4] = (Digits[3] << 7);
    #else
    Wire.write(0x70);
    Wire.write(0x3B);
    Wire.write(0xB5);
    Wire.write(0xD9);
    Wire.write(0x80);
    #endif

    for(int i=0;i<5;i++) Wire.write(data[i]);

    Wire.endTransmission();
    }

    //----------------------------------------------------------------------------

    void CDM4101::Init(void)
    {
    Blink = 0;

    Digits[0] = Segs[SPACE];
    Digits[1] = Segs[SPACE];
    Digits[2] = Segs[SPACE];
    Digits[3] = Segs[SPACE];

    Wire.beginTransmission(I2C_ADDR);
    Wire.write(CMD_MODE_SET);
    Wire.write(CMD_LOAD_DP);
    Wire.write(CMD_DEVICE_SEL);
    Wire.write(CMD_BANK_SEL);
    Wire.write(CMD_NOBLINK);
    Wire.write(0x05);
    Wire.write(0xD5);
    Wire.write(0x9B);
    Wire.write(0xFF);
    Wire.write(0x00);

    Wire.endTransmission();

    Ctr = 0;
    }

    //----------------------------------------------------------------------------

    void CDM4101::Command(byte cmd)
    {
    switch(cmd)
    {
    case CDM4101_BLINK_OFF :
    Blink = 0;
    Update();
    break;

    case CDM4101_BLINK_ON :
    Blink = 1;
    Update();
    break;

    case CDM4101_CLEAR :
    Digits[0] = Segs[SPACE];
    Digits[1] = Segs[SPACE];
    Digits[2] = Segs[SPACE];
    Digits[3] = Segs[SPACE];

    Update();
    break;

    default :
    break;
    }
    }

    //----------------------------------------------------------------------------

    char CDM4101::ConvertChar(char c)
    {
    if((c >= 'a') && (c <= 'z')) c = c - 'a' + ALPHA_START;
    else
    if((c >= 'A') && (c <= 'Z')) c = c - 'A' + ALPHA_START;
    else
    if((c >= '0') && (c <= '9')) c = c - '0';
    else
    if(c == '-') c = DASH;
    else
    if(c == '_') c = UNDERSCORE;
    else
    if(c == '*') c = ASTERISK;
    else c = SPACE;
    return c;
    }

    //----------------------------------------------------------------------------

    void CDM4101::DispChar(byte index, char c)
    {
    Digits[(int)index] = Segs[(int)(ConvertChar(c))];
    Update();
    }

    //----------------------------------------------------------------------------

    void CDM4101::DispStr(char *s)
    {
    byte i,c;

    for(i=0;i<CDM4101_NUM_DIGITS;i++) Digits[i] = Segs[SPACE];

    i = 0;

    while((i < 4) && s[i])
    {
    c = Segs[(int)(ConvertChar(s[i]))];

    Digits[i] = c;
    i++;
    }

    Update();
    }

    //----------------------------------------------------------------------------

    void CDM4101::DispStrTimed(char *s)
    {
    DispStr(s);
    Ctr = HOLD_TIME;
    }


    //----------------------------------------------------------------------------
    // display a decimal value, right justified.

    void CDM4101::DispDec(short n)
    {
    byte i;
    char str[5];

    if(n < -999L) n = -999L;
    if(n > 9999L) n = 9999L;

    for(i=0;i<5;i++) str[i] = 0;

    itoa(n, str, 10);

    while(str[3] == 0)
    {
    for(i=3;i>0;i--) str[i] = str[i-1];
    str[0] = ' ';
    }

    DispStr(str);
    }

    //----------------------------------------------------------------------------
    40 changes: 40 additions & 0 deletions cdm4101.h
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,40 @@
    #ifndef _CDM4101_H_
    #define _CDM4101_H_

    #include <inttypes.h>

    //----------------------------------------------------------------------------

    #define CDM4101_NUM_DIGITS 4

    //----------------------------------------------------------------------------
    // LCD commands.

    #define CDM4101_BLINK_OFF 6
    #define CDM4101_BLINK_ON 7
    #define CDM4101_CLEAR 8

    //----------------------------------------------------------------------------

    class CDM4101
    {
    public:
    void Init(void);
    void Command(byte cmd);
    void DispChar(byte index, char c);
    void DispStr(char *s);
    void DispStrTimed(char *s);
    void DispDec(short n);

    private:
    void Update(void);
    char ConvertChar(char c);

    byte Digits[CDM4101_NUM_DIGITS];
    byte Blink;
    byte Ctr;
    };

    //----------------------------------------------------------------------------

    #endif // _CDM4101_H_
  5. mohitbhoite created this gist Apr 16, 2023.
    88 changes: 88 additions & 0 deletions attiny85-satellite-lcd.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,88 @@
    #include "Adafruit_SHT31.h"
    #include <TinyWireM.h>
    #include <USI_TWI_Master.h>
    #include <avr/sleep.h> //Needed for sleep_mode
    #include <avr/wdt.h> //Needed to enable/disable watch dog timer
    #include <cdm4101.h>

    int ctr=1000;
    CDM4101 LCD;
    char data[25];
    int temperature = 0;

    bool displayToggle = 0;
    uint8_t loopCnt = 0;

    Adafruit_SHT31 sht31 = Adafruit_SHT31();

    void setup()
    {
    pinMode(3, INPUT_PULLUP);
    pinMode(4, INPUT_PULLUP);
    pinMode(5, INPUT_PULLUP);
    pinMode(1, INPUT_PULLUP);
    ADCSRA &= ~(1<<ADEN); //Disable ADC, saves ~230uA
    // put your setup code here, to run once:
    TinyWireM.begin();
    sht31.begin(0x44);
    LCD.Init();
    LCD.DispStr("sat6");
    delay(1000);
    set_sleep_mode(SLEEP_MODE_PWR_DOWN); //Power down everything, wake up from WDT
    sleep_enable();
    }

    //This runs each time the watch dog wakes us up from sleep
    ISR(WDT_vect) {
    //watchdog_counter++;
    displayToggle=!displayToggle;
    }

    void loop()
    {
    setup_watchdog(9); //Setup watchdog to go off after 8sec
    sleep_mode(); //Go to sleep! Wake up 8 sec later
    //BME280setup();
    //temperature = ((BME280temperature()/100)*1.8)+32;
    //BME280sleep();


    int temperature = (sht31.readTemperature()*1.8)+32;
    //int temperature = sht31.readTemperature();
    int humidity = sht31.readHumidity();
    if (displayToggle)
    {
    if ((temperature <110) && (temperature > -20))
    {
    sprintf(data,"%doF",temperature);
    LCD.DispStr(data);
    }
    }

    else
    {
    if ((temperature <101) && (temperature > 0))
    {
    sprintf(data,"%drH",humidity);
    LCD.DispStr(data);
    }
    }
    }

    //Sets the watchdog timer to wake us up, but not reset
    //0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms
    //6=1sec, 7=2sec, 8=4sec, 9=8sec
    //From: http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
    void setup_watchdog(int timerPrescaler) {

    if (timerPrescaler > 9 ) timerPrescaler = 9; //Limit incoming amount to legal settings

    byte bb = timerPrescaler & 7;
    if (timerPrescaler > 7) bb |= (1<<5); //Set the special 5th bit if necessary

    //This order of commands is important and cannot be combined
    MCUSR &= ~(1<<WDRF); //Clear the watch dog reset
    WDTCR |= (1<<WDCE) | (1<<WDE); //Set WD_change enable, set WD enable
    WDTCR = bb; //Set new watchdog timeout value
    WDTCR |= _BV(WDIE); //Set the interrupt enable, this will keep unit from resetting after each int
    }