Coder Social home page Coder Social logo

Monitoring TM1628 about tm16xx HOT 6 CLOSED

mutilator avatar mutilator commented on May 25, 2024
Monitoring TM1628

from tm16xx.

Comments (6)

mutilator avatar mutilator commented on May 25, 2024 2

Thanks for the quick response. Yea I had tried an opto-coupler and it wasn't working. I ended up using some tiny 3.3v relays and it worked fine, luckily only 4 buttons total.

Here are the images of both sides of the board.
2024-01-20 15 43 20
2024-01-20 15 43 37

Also here is the code I used to output the screenshot above in-case anyone else finds this later and wants to play.

It's running on an ESP-32 module

// Datasheet for TM1628 - https://aitendo3.sakura.ne.jp/aitendo_data/product_img/ic/LED-driver/TM1628english.pdf
#define PIN_DATA    26
#define PIN_CLOCK   18
#define PIN_STROBE  19


byte SEG_DIGITS[] = {
  0b11101011, // 0
  0b10000001, // 1
  0b11011010, // 2
  0b11011001, // 3
  0b10110001, // 4
  0b01111001, // 5
  0b01111011, // 6
  0b11000001, // 7
  0b11111011, // 8
  0b11110001, // 9
  0b11110011, // A
  0b11111011, // B
  0b01101010, // C
  0b11101011, // D
  0b01111010, // E
  0b01110010  // F
};

byte BIT_POWER = 0b10000000;
byte BIT_FAN_HIGH = 0b01000000;
byte BIT_FAN_MEDIUM = 0b00100000;
byte BIT_FAN_LOW = 0b00010000;
byte BIT_DEFROST = 0b00000010;
byte BIT_TANK_FULL = 0b00000001;


bool isStrobeActive = false; // If stroibe is active we're reading data
bool processByte = false; // Whether the main loop should process the data read

int bitsRead = 0; // how many bits read so far, we kick it at 8 no matter what
byte myData = 0; // Last data byte read from the serial
byte waitByteIdx = 0; // which byte of the 6 are we processing
bool gettingDisplay = false; // if we're parsing the 0xC0 command that pushes data to the display
byte aryIdx = 0; // where we're writing to the array
byte byteCache[5]; // small array in case we get data faster than we're processing it

int digitOnes = 0;
int digitTens = 0;
int powerOn = false;
int fanSpeed = 0; //0 = auto, 1 = low, 2 = med, 3 = high
int tankFull = false;
int defrosting = false;

void IRAM_ATTR strobeActive() {
  if (!digitalRead(PIN_STROBE))
  {
    isStrobeActive = true;
  } else {
    isStrobeActive = false;
  }
}


void IRAM_ATTR clockRead() {
  if (!isStrobeActive)
    return;

  bitsRead++;
  myData >>= 1;
  if (digitalRead(PIN_DATA))
    myData |= 0x80;
  
  if (bitsRead % 8 == 0)
  {
    byteCache[aryIdx] = myData;
    aryIdx++;
    processByte = true;
  }
}


void setup()
{
  Serial.begin(115200);
  pinMode(PIN_DATA, INPUT);
  pinMode(PIN_CLOCK, INPUT);
  pinMode(PIN_STROBE, INPUT);

  attachInterrupt(PIN_STROBE, strobeActive, CHANGE);
  attachInterrupt(PIN_CLOCK, clockRead, RISING);
}


void loop () {
  processIncomingData();
  if (millis() % 5000 == 0) // show something roughly every 5 seconds
    printStatus()
}

void printStatus()
{
  static char fs[7];
    static char pw[4];
    static char tf[6];
    static char df[4];
    switch (fanSpeed)
    {
      case 0:
        strcpy(fs,"Auto");
        break;
      case 1:
        strcpy(fs,"Low");
        break;
      case 2:
        strcpy(fs,"Medium");
        break;
      case 3:
        strcpy(fs,"High");
        break;
    }

    if (powerOn)
      strcpy(pw, "On");
    else
      strcpy(pw, "Off");

    if (tankFull)
      strcpy(tf, "Full");
    else
      strcpy(tf, "Empty");

    if (defrosting)
      strcpy(df, "Yes");
    else
      strcpy(df, "No");

    Serial.print("Current Humidity: ");
    Serial.print(digitTens);
    Serial.println(digitOnes);
    Serial.print("Power: ");
    Serial.println(pw);
    Serial.print("Fan Speed: ");
    Serial.println(fs);
    Serial.print("Water Reservoir: ");
    Serial.println(tf);
    Serial.print("Defrosting: ");
    Serial.println(df);
    Serial.println("");
    Serial.println("");
}


void processIncomingData()
{
  if (processByte)
  {
    for(int i = aryIdx - 1; i >= 0; i--)
    {
      if (gettingDisplay)
      {
        switch (waitByteIdx)
        {
          case 0: // LED STATUS_LIGHTS
            powerOn = (byteCache[i] & BIT_POWER) == BIT_POWER;
            fanSpeed = (byteCache[i] & BIT_FAN_HIGH) == BIT_FAN_HIGH?3:(byteCache[i] & BIT_FAN_MEDIUM) == BIT_FAN_MEDIUM?2:(byteCache[i] & BIT_FAN_LOW) == BIT_FAN_LOW?1:0;
            tankFull = (byteCache[i] & BIT_TANK_FULL) == BIT_TANK_FULL;
            defrosting = (byteCache[i] & BIT_DEFROST) == BIT_DEFROST;
            break;
          case 1: // empty bit? could be an issue with how we're reading data
            break;
          case 2:
            digitOnes = getDigit(byteCache[i]);
            break;
          case 3: // empty bit? could be an issue with how we're reading data
            break;
          case 4:
            digitTens = getDigit(byteCache[i]);
            break;
          case 5: // empty bit? could be an issue with how we're reading data
            gettingDisplay = false; // This is the last empty bit from the 0xC0
            break;
        }
        waitByteIdx++;
      }
      if (byteCache[i] == 0xC0) // Command 3 from datasheet
      {
        waitByteIdx = 0;
        gettingDisplay = true; // Start interpreting the following bytes as segment display
      }
      //Serial.println(byteCache[i],HEX);
    }
    aryIdx = 0;
    
    processByte = false;
  }
}

byte getDigit(byte myDigit)
{
  for(int i = 0; i < 9; i++)
    if (myDigit == SEG_DIGITS[i])
      return i;

  return 0; //uh give em something i guess?
}

from tm16xx.

mutilator avatar mutilator commented on May 25, 2024 1

After a bit of playing around I wrote something from scratch so I can read the data but I think emulated button presses are out of the question because I can't respond to the 'are you pressing buttons' command because the TM1628 is also responding.

image

from tm16xx.

mutilator avatar mutilator commented on May 25, 2024 1

I turned this into an ESPhome component integration here: https://github.com/mutilator/esphome/tree/dev/esphome/components/bdh450

Might give someone a bit of a start on a similar path.

from tm16xx.

maxint-rd avatar maxint-rd commented on May 25, 2024

Hello, interesting project! It seems really useful to be able to have some remote control to your dehumidifier. My own dehumidifier is not too smart either, so on a daily basis I have to go check it's light to see if the reservoir is full. Would be nice to get a notification on my phone!

So your dehumidifier has a TM1628? In the main readme of this library I'm collecting a list of real world devices using a TM16xx chip. Perhaps you can share a picture of the PCB, showing the chip?

Unfortunately this library only works in one direction and can only be used to drive TM16xx chips. It cannot emulate a TM16xx chip, but you may find it useful to drive a test circuit and analyze its workings. BTW. In issue #37 someone asked a similar question regarding the TM1651 and I gave some more elaborate responses.

Good to see you already implemented something and that you have successfully captured the display data and translated it to a readable form. Well done!

With regard to emulating the button presses, I see some potential. I think this requires additional hardware and cannot be done just in software. You first need to see which of the keyboard lines of the actual TM1628 are connected to the buttons (K1/K2 vs. KS1-KS8). Based on that you would need to solder something to the keyboard lines to make an electrical connection. Once you want to generate a remote button press, you briefly connect these lines to trigger the key-scanning process of the TM1628.

On page 12 of the english datasheet you can find the Application Circuit diagram. Since the TM1628 is meant for common cathode displays, that would suggest that the keyscan checks to see if the KS1-KS8 ouputs are set high by a reading the K1/K2 input lines. Perhaps having a logic mosfet between these will work; eg. between KS1 and K1. Alternatively you could try an opto-coupler, but that may have too high resistance when switched on. Of course you could also use a relais, but those are more bulky/expensive. Before destroying the dehumidifier, I suggest you to first make a test display using some sacrificial TM1628 chips to experiment with.

from tm16xx.

maxint-rd avatar maxint-rd commented on May 25, 2024

Very nice project with great success. Congratulations !
Thank you for sharing the pictures and your code. I've added a link to this issue in the main readme so that your contribution is highlighted and the issue can be closed.

from tm16xx.

maxint-rd avatar maxint-rd commented on May 25, 2024

Very nice! Good example of how to make a device smart and integrate it in your household. Thank you for sharing your code!

from tm16xx.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.