237 lines
6.5 KiB
Arduino
237 lines
6.5 KiB
Arduino
|
/*
|
||
|
reads out a lcd display
|
||
|
based on:
|
||
|
https://lowpowerlab.com/forum/projects/moteino-kitchen-scale/
|
||
|
|
||
|
An Arduino Pro Micro was used first as a simple logic analyser,
|
||
|
to find the common pins and the segment pins. See the other sketch.
|
||
|
Later the same arduino was put with this sketch inside the scale to provide
|
||
|
serial output via usb.
|
||
|
|
||
|
This paricular display is part of a transtek kitchen scale
|
||
|
(pcb label: tsk759)
|
||
|
|
||
|
The connector in numbered like this
|
||
|
|
||
|
----top border of the board----
|
||
|
|
||
|
0 2 4 6 8 10 12 14
|
||
|
1 3 5 7 9 11 13 15
|
||
|
|
||
|
Pins 0 to 3 are the common pins, but since they are phase shifted by 90° only one
|
||
|
is needed.
|
||
|
|
||
|
Only Pins 8 to 15 carry useful information. All others are ignored.
|
||
|
|
||
|
*/
|
||
|
|
||
|
byte samples[2][56];
|
||
|
|
||
|
// lcd mapping
|
||
|
int seg1[2] = { PINB2, PINB6 };
|
||
|
int seg2[2] = { PINB4, PINB3 };
|
||
|
int seg3[2] = { PINB2, PINB6 };
|
||
|
int seg4[2] = { PINB2, PINB6 };
|
||
|
|
||
|
void setup() {
|
||
|
Serial.begin(115200);
|
||
|
}
|
||
|
|
||
|
void loop() {
|
||
|
get_samples(); // reads out the registers
|
||
|
if (Serial.read() > 0) {
|
||
|
int pulse = get_pulse();
|
||
|
//print_segments(pulse);
|
||
|
print_4digit(pulse);
|
||
|
print_3digit(pulse);
|
||
|
print_digit(pulse, seg2);
|
||
|
print_digit(pulse, seg1);
|
||
|
Serial.println();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void get_samples() {
|
||
|
int f=0;
|
||
|
while (f<56) {
|
||
|
samples[0][f] = PINB;
|
||
|
samples[1][f] = PIND;
|
||
|
delayMicroseconds(333); // = 1/3 ms. three samples in 1ms, which is the approximate pulse width.
|
||
|
f++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// try to find the position, where the control signal triggers
|
||
|
// looking for a sequence of more than four ones seams sufficient
|
||
|
int get_pulse() {
|
||
|
int n = 0;
|
||
|
int f = 0;
|
||
|
while (f<30) {
|
||
|
if ((samples[1][f]& (1 << PIND3))) {
|
||
|
n++;
|
||
|
if (n>4) break;
|
||
|
}
|
||
|
else n=0;
|
||
|
f++;
|
||
|
}
|
||
|
return f - 3; // sets the index in the first 1ms of the trigger event
|
||
|
}
|
||
|
|
||
|
void print_digit(int start, int seg[]) {
|
||
|
byte digit = InterpretSevenSegmentSet(
|
||
|
samples[0][start + 18]&(1<<seg[0]), // A or D
|
||
|
samples[0][start + 6]&(1<<seg[1]), // B
|
||
|
samples[0][start + 12]&(1<<seg[1]), // C
|
||
|
samples[0][start]&(1<<seg[1]), // A or D
|
||
|
samples[0][start + 12]&(1<<seg[0]), // E
|
||
|
samples[0][start]&(1<<seg[0]), // F
|
||
|
samples[0][start + 6]&(1<<seg[0]) // G
|
||
|
);
|
||
|
if (digit == 255) return;
|
||
|
else Serial.print(digit, DEC);
|
||
|
}
|
||
|
|
||
|
void print_4digit(int start) {
|
||
|
// print 4th digit
|
||
|
// B1 is 8
|
||
|
// D4 is 9
|
||
|
byte digit = InterpretSevenSegmentSet(
|
||
|
samples[0][start + 18]&(1<<PINB1), // A or D
|
||
|
samples[1][start + 6]&(1<<PIND4), // B
|
||
|
samples[1][start + 12]&(1<<PIND4), // C
|
||
|
samples[1][start]&(1<<PIND4), // A or D
|
||
|
samples[0][start + 12]&(1<<PINB1), // E
|
||
|
samples[0][start]&(1<<PINB1), // F
|
||
|
samples[0][start + 6]&(1<<PINB1) // G
|
||
|
);
|
||
|
if (digit == 255) return;
|
||
|
else Serial.print(digit, DEC);
|
||
|
}
|
||
|
|
||
|
void print_3digit(int start) {
|
||
|
// print 3rd digit
|
||
|
// D7 is A
|
||
|
// B5 is B
|
||
|
byte digit = InterpretSevenSegmentSet(
|
||
|
samples[1][start + 18]&(1<<PIND7), // A or D
|
||
|
samples[0][start + 6]&(1<<PINB5), // B //
|
||
|
samples[0][start + 12]&(1<<PINB5), // C //
|
||
|
samples[0][start]&(1<<PINB5), // A or D
|
||
|
samples[1][start + 12]&(1<<PIND7), // E //
|
||
|
samples[1][start]&(1<<PIND7), // F
|
||
|
samples[1][start + 6]&(1<<PIND7) // G
|
||
|
);
|
||
|
if (digit == 255) return;
|
||
|
else Serial.print(digit, DEC);
|
||
|
}
|
||
|
|
||
|
void print_2digit(int start) {
|
||
|
// print 2nd digit
|
||
|
// B4 is C
|
||
|
// B3 is D
|
||
|
byte digit = InterpretSevenSegmentSet(
|
||
|
samples[0][start + 18]&(1<<PINB4), // A or D
|
||
|
samples[0][start + 6]&(1<<PINB3), // B //
|
||
|
samples[0][start + 12]&(1<<PINB3), // C //
|
||
|
samples[0][start]&(1<<PINB3), // A or D
|
||
|
samples[0][start + 12]&(1<<PINB4), // E //
|
||
|
samples[0][start]&(1<<PINB4), // F
|
||
|
samples[0][start + 6]&(1<<PINB4) // G
|
||
|
);
|
||
|
Serial.print(digit, DEC);
|
||
|
}
|
||
|
|
||
|
void print_1digit(int start) {
|
||
|
// print 1st digit
|
||
|
// B2 is E
|
||
|
// B6 is F
|
||
|
byte digit = InterpretSevenSegmentSet(
|
||
|
samples[0][start + 18]&(1<<PINB2), // A or D
|
||
|
samples[0][start + 6]&(1<<PINB6), // B //
|
||
|
samples[0][start + 12]&(1<<PINB6), // C //
|
||
|
samples[0][start]&(1<<PINB6), // A or D
|
||
|
samples[0][start + 12]&(1<<PINB2), // E //
|
||
|
samples[0][start]&(1<<PINB2), // F
|
||
|
samples[0][start + 6]&(1<<PINB2) // G
|
||
|
);
|
||
|
Serial.print(digit, DEC);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
attention! in this decision tree '1' represents off-segments
|
||
|
maybe you have to inverse it.
|
||
|
|
||
|
for a given digit, we have:
|
||
|
A
|
||
|
F B
|
||
|
G
|
||
|
E C
|
||
|
D
|
||
|
then, the algorithm is:
|
||
|
*/
|
||
|
byte InterpretSevenSegmentSet(byte A, byte B, byte C, byte D, byte E, byte F, byte G ) {
|
||
|
byte digit;
|
||
|
if(E) {
|
||
|
if(F) {
|
||
|
if(A) {
|
||
|
if(B) digit = 0xff; // off
|
||
|
else {
|
||
|
if(D) digit = 1;
|
||
|
else digit = 7;
|
||
|
}
|
||
|
}
|
||
|
else digit = 3;
|
||
|
}
|
||
|
else {
|
||
|
if(A) digit = 4;
|
||
|
else {
|
||
|
if(B) digit = 5;
|
||
|
else digit = 9;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
if(B) {
|
||
|
if(C) {
|
||
|
if(A) digit = 114; // "r"
|
||
|
else digit = 69; // "E"
|
||
|
}
|
||
|
else digit = 6;
|
||
|
}
|
||
|
else {
|
||
|
if(G) digit = 0;
|
||
|
else {
|
||
|
if(C) digit = 2;
|
||
|
else digit = 8;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return digit;
|
||
|
}
|
||
|
|
||
|
// this is only needed once to map the pins correcly when using this script for another display
|
||
|
// here the case index corresponds to the number of the pad at the display to make mapping easier.
|
||
|
void print_segments(int start) {
|
||
|
int i=2;
|
||
|
while(i<16) {
|
||
|
int f = start;
|
||
|
Serial.print(i, HEX); Serial.print(": ");
|
||
|
while (f< (start + 23))
|
||
|
{
|
||
|
switch(i) {
|
||
|
case 9: if( (samples[1][f]& (1 << PIND4))) Serial.print("1"); else Serial.print("0"); break;
|
||
|
case 10: if( (samples[1][f]& (1 << PIND7))) Serial.print("1"); else Serial.print("0"); break;
|
||
|
case 12: if( (samples[0][f]& (1 << PINB4))) Serial.print("1"); else Serial.print("0"); break;
|
||
|
case 11: if( (samples[0][f]& (1 << PINB5))) Serial.print("1"); else Serial.print("0"); break;
|
||
|
case 15: if( (samples[0][f]& (1 << PINB6))) Serial.print("1"); else Serial.print("0"); break;
|
||
|
case 14: if( (samples[0][f]& (1 << PINB2))) Serial.print("1"); else Serial.print("0"); break;
|
||
|
case 13: if( (samples[0][f]& (1 << PINB3))) Serial.print("1"); else Serial.print("0"); break;
|
||
|
case 8: if( (samples[0][f]& (1 << PINB1))) Serial.print("1"); else Serial.print("0"); break;
|
||
|
}
|
||
|
f = f + 6;
|
||
|
}
|
||
|
Serial.println();
|
||
|
i++;
|
||
|
}
|
||
|
}
|