Comments (6)
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.
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.
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.
from tm16xx.
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.
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.
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.
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)
- Redefine Pins HOT 1
- Redback 7-segment led and button module with TM1652 HOT 4
- Add pinMode() to sendData() and getButtons() HOT 1
- Example for TM1640 with common anode 8x8 bicolor led matrix? HOT 17
- TM1650 Arduino library for 2 x 7 led display HOT 7
- regarding interfacing of tm1640 HOT 12
- Can I act _as_ a TM1651? HOT 4
- Problem while using this library with ESP32 HOT 3
- Hello Any help on TM1621 HOT 2
- how we can use 4 segment with dot HOT 1
- Another TM1652 device HOT 2
- Halt when useing RP2040 with TM1652 HOT 2
- TM16xxDisplay.cpp bug HOT 1
- Request: Flip 8x8 matrix HOT 18
- How do you control the TM1638 discrete LEDS? HOT 2
- Button numbering question for TM1638 LED&KEY module (8 LEDS, 8 digits, 8 Buttons)? HOT 2
- Support for TM1618? HOT 14
- Problems with TM1618 HOT 15
- Request: Brightness scaled [0-255] instead of [0-7] HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tm16xx.