I just bought an Arduino. Or to be more specific, an enhanced clone of the Arduino Leonardo : the Olimex OLIMEXINO-32U4. This board features, unlike the original Leonardo board, a better power that allows it to run on 5v, 3.3v, or on li-ion battery. It also sports two leds, a button and an extension port.
I plan to use it with a bluetooth module that runs only on 3.3v, so the ability to power this arduino on 3.3v will ease it !
For my start project, I want to try to use an old Futaba GP1006C02 VFD graphic display. It’s a mid 90’s part that I collected in a garbage and that was lying on a shelf since. I wondered if I could use it to make a status display for my home server.
Hardware:
The VFD is addressed like a RAM. So I had to use a lot of I/O to handle it. 13 address lines, 8 data bits and 4 control lines. Problem, I only have 23 I/O available on the arduino (20 on the headers and 3 more on the extension port or the ICSP header). The ATMega 32U4 normally provides 26 I/O but two are used by the arduino firmware to drive the USB RX/TX leds and the last one is used by the button. I don’t want to modify the Arduino board and software to use them so I’ll had to find a way to wire everything.
First obvious trick, the /CS and /MERQ signals can be driven by the same I/O according the VFD datasheet. Second trick, I don’t need read access to the display memory, so I can wire /RD to 5v. But I still need 2 I/O. So I decide to use a binary counter to generate the address. I find in a drawer a good old 4029 4 bits binary/décimal counter/decounter. With just a reset and pulse signals, I can drive 4 address bits.
Now, I want an easy way to wire everything. I don’t want to make a custom PCB and just use a stripboard. To simplify wiring, I decided to not try to wire everything in an ordered way. The software will have to convert addresses and datas to the right ports and I/O. But I found a way to not shuffle things too much. I managed to stick the datas to the 4 higher bits of ports B and F, and the address to the 7 available bits of port D and the 4 bits of the counter. I decided to put the 4 bits of the counter to A3 through A7. This can seem odd, but when you look at the way the addresses map to pixels in the VFD datasheet, mapping at this address allow me to push 16 continuous columns of 8 pixels. The display will be sliced in 8 rows of 16 blocks of 16×8 pixels.
The control bits (/CS, /WR, CP and PL) are wired to nearest I/O available. Thank to the use of the counter, I have 2 I/O available. Maybe I could wire the /RD signal after all 😉
Arduino software :
There’s some small challenges with the software. The first one is to map a data byte to the 4 higher bits of the port B and F. Odd bits go to port F and pair bits go to port B.
There maybe an optimized way to do it, but the only way I find was to do it bit by bit. Mask the bit, shift it to it’s position, and repeat… Performance is not really an issue actually, so I’ll stick with this…
1 2 3 4 5 6 7 8 9 10 11 12 13 | void setData(byte d) { PORTB = (PORTB & 0x0F) | (( ((d & 0x40) << 1) | ((d & 0x10) << 2) | ((d & 0x04) << 3) | ((d & 0x01) << 4)) & 0xF0); PORTF = (PORTF & 0x0F) | (( ((d & 0x80) ) | ((d & 0x20) << 1) | ((d & 0x08) << 2) | ((d & 0x02) << 3)) & 0xF0); } |
The second challenge is to convert row and column to a valid address on port B. I decided to use two maps for the 8 rows and 16 columns.
1 2 3 4 5 6 7 | void setAddress(byte l, byte c) { byte lmap[] = { 0x00, 0x08, 0x04, 0x0C, 0x02, 0x0A, 0x06, 0x0E }; byte cmap[] = { 0x00, 0x01, 0x40, 0x41, 0x10, 0x11, 0x50, 0x51, 0x80, 0x81, 0xC0, 0xC1, 0x90, 0x91, 0xD0, 0xD1 }; PORTD = (PORTD & 0x20) | lmap[l] | cmap[c]; } |
The rest of the code is easy to understand, I won’t detail it. It allows me to send bitmaps and controls commands over USB.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | #define DELAY_62ns5 __asm__("nop\n\t") #define SET(_port, _bit) _port |= 1 << _bit #define UNSET(_port, _bit) _port &= ~(1 << _bit) void setData(byte d) { PORTB = (PORTB & 0x0F) | (( ((d & 0x40) << 1) | ((d & 0x10) << 2) | ((d & 0x04) << 3) | ((d & 0x01) << 4)) & 0xF0); PORTF = (PORTF & 0x0F) | (( ((d & 0x80) ) | ((d & 0x20) << 1) | ((d & 0x08) << 2) | ((d & 0x02) << 3)) & 0xF0); } void setAddress(byte l, byte c) { byte lmap[] = { 0x00, 0x08, 0x04, 0x0C, 0x02, 0x0A, 0x06, 0x0E }; byte cmap[] = { 0x00, 0x01, 0x40, 0x41, 0x10, 0x11, 0x50, 0x51, 0x80, 0x81, 0xC0, 0xC1, 0x90, 0x91, 0xD0, 0xD1 }; PORTD = (PORTD & 0x20) | lmap[l] | cmap[c]; } void resetBlock() { PORTF |= 0x01; DELAY_62ns5; PORTF &= ~0x01; DELAY_62ns5; } void incBlock() { PORTF |= 0x02; DELAY_62ns5; PORTF &= ~0x02; DELAY_62ns5; } void delayNs() { } void write() { PORTC &= ~0x40; // unset /CS DELAY_62ns5; // delay > 200ns DELAY_62ns5; DELAY_62ns5; PORTC &= ~0x80; // unset /WR DELAY_62ns5; // delay > 100nx PORTC |= 0xC0; // set /CS and /WR } char page_displayed = 0; char page_writed = 0; void setPage() { PORTB |= 0x02; // set A12 setData((page_displayed & 0x03) | ((page_writed << 2) & 0x0C)); write(); PORTB &= ~0x02; // unset A12 } void showPage(byte page) { page_displayed = page; setPage(); } void setWritePage(byte page) { page_writed = page; setPage(); } void setLuminosity(byte page) { PORTB |= 0x02; // set A12 PORTE |= 0x40; // set A11 page &= 0x0F; if(page && page < 0x06) page = 0x06; setData(page); write(); PORTB &= ~0x02; // unset A12 PORTE &= ~0x40; // unset A11 } void setup() { byte c, l, i, j; // all ports are outputs DDRB = DDRC = DDRD = DDRE = DDRF = 0xFF; PORTC &= ~0x40; // unset /CS PORTC |= 0x80; // set /WR resetBlock(); setPage(); for(l = 0; l < 8; l++) { for(c = 0; c < 16; c++) { setAddress(l, c); i = 16; while(i) { incBlock(); setData(0x00); write(); i--; } } } setLuminosity(15); Serial.begin(115200); } char anim = 0; void loop() { char i, l, c; byte code; if(Serial.available() > 0) { code = Serial.read(); switch(code & 0xF0) { case 0x80: setWritePage(code & 0x0F); break; case 0x90: showPage(code & 0x0F); break; case 0xA0: setLuminosity(code & 0x0F); break; case 0xB0: // Blank for(l = 0; l < 8; l++) { for(c = 0; c < 16; c++) { setAddress(l, c); i = 16; while(i) { incBlock(); setData(0x00); write(); i--; } } } break; case 0xC0: // Full on for(l = 0; l < 8; l++) { for(c = 0; c < 16; c++) { setAddress(l, c); i = 16; while(i) { incBlock(); setData(0xFF); write(); i--; } } } break; case 0xD0: // Test patern for(l = 0; l < 8; l++) { for(c = 0; c < 16; c++) { setAddress(l, c); i = 16; while(i) { i--; incBlock(); setData(i < 8 ? (1 << i) : (0x80 >> (i - 8))); write(); } } } break; case 0xE0: // Start stop animation patern anim = code & 1 ? 8 : 0; break; case 0xF0: // Light/Clear dot anim = 0; // TODO // Need hardware modification for read function break; default: // address followed by 16 bytes of data setAddress((code & 0x70) >> 4, code & 0x0f); i = 16; while(i) { while(Serial.available() <= 0) {} setData(Serial.read()); write(); incBlock(); i--; } } } if(anim & 0x8) { for(l = 0; l < 8; l++) { for(c = 0; c < 16; c++) { setAddress(l, c); i = 16; while(i) { i--; incBlock(); setData(1 << ((i + anim) & 0x07)); write(); } } } anim++; if(anim & 0x10) anim = 0x08; } } |
The software takes commands over USB serial link. The first byte is the command byte. If the higher bit is 0, then bits 6 to 4 encode the row, and bits 3 to 0 encode the column. The control byte is then followed by 16 data bytes that correspond to the 16 columns of the addressed block.
If the first bit is 0, then the commands are :
Bit | Command | |||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
1 | 0 | 0 | 0 | 0 | 0 | page | Read / Write page | |
1 | 0 | 0 | 1 | 0 | 0 | page | Displayed page | |
1 | 0 | 1 | 0 | luminosity | Set luminosity | |||
1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | Blank |
1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | Full on |
1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | Test Pattern (/\/\/\/\) |
1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | Test animation (sliding ////) |
1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | Not used |
Computer software:
I wrote a small python script that sends an hard coded image to the VFD :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | import serial, pprint a = """ XXX XXX XXXXXXXXX XXXXXXX XXXXXX XXX XXXXXXX XXXXXXXXXXXXX XXXX XXX XXXXXXX XXXXXXXXXX XXXXXXX XXXXXXX XXXXXXXXXXXXXX XXXXXXXX XXXXXXX XXXXXXXXX XXXXXXXXXXXXX XXXXXXXX XXXXXXXXX XXXXXXXXXXXXXXXXXX XXXXXXXXX XXXXXXX XXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXXXXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXX XXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXX XXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXXXXXXXXXX XXXXXXXXXXX XXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXX XXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXXXXX XXXXXXXXXXX XXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXXXX XXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXXX XXXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXX XXXXXXXXX XXXXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXX XXXXXXXXX XXXXXXXXXX XXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXX XXXXXXXXX XXXXXXXXXX XXXXXXX XXXXXXXXXXX XXXXXXXXXX XXXXXXXXXXX XXXXXXXXXXXX XXXXXXXXXX XXX XXX XXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXXX XXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXXXX XXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXX XXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXX XXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXX XXX XXXXXXXXXX XXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXX XXXXXXX XXXXXXXXXXX XXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXX XXXXXXXXX XXXXXXXXXXX XXXXXXXXX XXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXX XXXXXXXXXXX XXXXXXXXXX XXXXXXXXX XXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXX XXXXXXXXXXX XXXXXXXXXX XXXXXXX XXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXX XXXXXXXXXXX X X XXXXXXXX XXXXXXX XXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXX XXXXXXXXXXX X XXXXXXXX XXX XXXXXXX XXXXXXXXX XXXXXXXXXXXXXXXXXX XXXXXXXXXX XXXXXXXXXXX X X XXXX XXXXXX XXXXXXXXXXX X XXXXXXXXX X X XXXXXXXXX X XXXXX X X X """ try: ser = serial.Serial('/dev/ttyACM0', 115200) except Exception: ser = serial.Serial('/dev/ttyACM1', 115200) a=a.replace('\n', '') def block(c, l): s = chr(l * 16 + c) for i in range(16): b = 0; for j in range(8): offset = c * 16 + i + 256 * (l * 8 + j) # print 'c=%d, l=%d, i=%d, j=%d, c * 16 + i + 257 * (l * 8 + j)=%d, b=%02x, %s' % (c,l,i,j,offset, b, a[offset]) if a[offset] != ' ': b |= 2**j s += chr(b) return s if 1: for c in range (16): for l in range(8): s = block(c, l) #print ' '.join('%02x' % ord(l) for l in s) ser.write(s) print ' '.join('%02x' % ord(l) for l in block(15,7)) print len(a), len(a) / 64, len(a) / 256 |
Conclusion:
I’ve had fun playing with this, but unfortunately I think I won’t use this VFD as a side display for my home server. First reason is that it is really greedy. It use ~2A @ 5v, that’s 10W. I can use a small color LCD that will be nicer and more power friendly ! And the second reason is that it make high pitched noise.
1 Commentaire
Excellent moi, j avais monter un kit openenergymonitor chez moi pour faire du monitoring température , conso en watt de 3 phases via le net et optimiser des interdictions de marche ou forçage de chauffages le compteur elec
Un truc pas mal pour bidouiller
GL