What a bargraph is? It is a bar of diodes indicating a level of something. This circuit lets you control a bargraph of 10 LEDs, 8 controlled digitally from the program and the other two manually from the board. It may be particulary usefull where there is a need for displaying anything, especially when it\'s too dark to read LCD screen. You can display progress of a process taking place, any number or an internal state of the program. It is very easy now to signalize different events to the operator who is not watching the screen.

The circuit design is based on PCF8574 chip which is an 8-bit I/O port expander for I²C interface. This interface is used by Lego for reading digital sensors like the ultrasonic sensor. I used it to control LEDs. The PCF8574 chip provides 8 universal input / output digital ports. I used these ports as outputs. By sending a command to the chip I can set every port to be on or off. Unfortunatelly, these ports cannot drive LEDs directly due to low output current provided. To solve that I used ULN2803 chip which amplifies the signal and lights diodes. I used a 10-LEDs bargraph, but both chips controls only 8 of them. The other two can be set on or off manually using jumpers. Each LED has its own resistor which is always necessary when lighting one. I uses a resistor ladder (8x510Ω) for the digitally controlled diodes and two single resistors of the same value for the manually controlled ones. The circuit includes a capacitor for the power supply line and two required 10kΩ resistors for I²C communication line.

I find standard RJ-12 sockets (similar to those used in Lego) too big and impractical in custom made electronics. I've decided to use goldpin-type sockets and plugs from this project henceforth. The only drawback of this solution is that there is a possibility to connect it the wrong way. I solved this by marking one side of the plug and the socket with a piece of tape.

Now some details about controling the bargraph and PCF8574 chip. The chip has 8 programmable addresses. I chose the lowest one - 0x40. To set the diodes on or off you need to send through I²C this address followed by one byte (8 bits) that sets the diode on (bit 1) or off (bit 0). In NXC programming language it looks like this:
byte x[] = {0x40, 0x01}; I2CWrite(S1, 0, x); The first line creates an array consisting of two bytes. The first one is an address and should always be 0x40. The second one is a number 01 in hexadecimal code, which is 00000001 in binary code. Every bit controls one diode setting it on or off. In the second line I use the I2CWrite function which will take care of the whole communication process. It takes 3 arguments: the port to which a bargraph is connected (here the first one), then 0 (always zero), and the last is a name of an array created before. You should always remember to configure the input port before using it. You can do it like this:
SetSensorLowspeed(S1); This function takes only one parameter which is a port number to which the bargraph is connected (here the first one).

Here on the left you can find the electric schematic, PCB layout and the PCB mask. Click on the image to enlarge it. By clicking here you can download the PCB project created in KiCad.

Here you can find a video showing the circuit in action and program code used during the video test. Feel free to comment on this project!



Program code

//author: Krzysztof Kapusta, All rights reserved #define BIT1 0x01 #define BIT2 0x02 #define BIT3 0x04 #define BIT4 0x08 #define BIT5 0x10 #define BIT6 0x20 #define BIT7 0x40 #define BIT8 0x80 byte BIT[] = {BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, BIT8}; #define PORT S1 #define ADDR 0x40 task main() { byte buf[2] = {ADDR, 0}; SetSensorLowspeed(PORT); for (int i = 0; i<5; i++) { for (int b = 0; b < 8; b++) { buf[1] = BIT[b]; I2CWrite(PORT, 0, buf); Wait(MS_100); } } for (int i = 0; i<3; i++) { byte con = 0x00; for (int b = 7; b>=0; b--) { for (int x = 0; x<b+1; x++) { buf[1] = con | BIT[x]; I2CWrite(PORT, 0, buf); Wait(MS_70); } con |= BIT[b]; } } for (int i = 0; i<5; i++) { for (int b = 0; b<8; b++) { buf[1] = BIT[b]; I2CWrite(PORT, 0, buf); Wait(MS_40); } for (int b = 7; b>=1; b--) { buf[1] = BIT[b]; I2CWrite(PORT, 0, buf); Wait(MS_40); } buf[1] = BIT[1]; I2CWrite(PORT, 0, buf); Wait(MS_40); } for (int i = 0; i<1; i++) { buf[1] = 0x00; do { I2CWrite(PORT, 0, buf); Wait(MS_50); buf[1]++; } while (buf[1] != 0x00); } for (int i = 0; i<5; i++) { buf[1] = 0xff; I2CWrite(PORT, 0, buf); Wait(MS_400); buf[1] = 0x00; I2CWrite(PORT, 0, buf); Wait(MS_400); } for (int i = 0, int b = 3; i<100; i++) { buf[1] = BIT[abs(b%8)]; I2CWrite(PORT, 0, buf); if (Random(2) == 0) b++; else b--; Wait(MS_50); } for (int i = 0, int b1 = 3, int b2 = 6; i<100; i++) { buf[1] = BIT[abs(b1%8)] | BIT[abs(b2%8)]; I2CWrite(PORT, 0, buf); if (Random(2) == 0) b1++; else b1--; if (Random(2) == 0) b2--; else b2++; Wait(MS_50); } for (int i = 0; i<2; i++) { for (int b = 7; b>=0; b--) { buf[1] = BIT[b]; I2CWrite(PORT, 0, buf); Wait((b+1)*40); } } buf[1] = 0x00; for (int i = 0; i<20; i++) { I2CWrite(PORT, 0, buf); buf[1] |= BIT[Random(8)]; Wait(MS_200); } }

Show/hide all the code



No comments yet. Be the first one! Post a comment!

Post your comment