Attiny84 i2c strange behavior - Page 1
Forum section: electronics / general

author: doodlebob
author_rank: Newbie
timestamp: January 01, 2021, 04:49:31 am
content: About 3 weeks ago I started on a project that required custom 7 segment displays. I ended up writing my own code for use with a MCU and 7 transistors. The code works, although there is a noticeable flicker because I am simulating PWM. I did not want 224 led's to have their own current limiting resistors and I am also able to change the brightness this way. I have 8, 7 segment displays in total and the only communication that I though would be practical was i2c.Problems - When I plug in all 8, strange things start happening. Sometimes a display will just turn off, but when the master gets to that address the i2c lines are low and stay low. Other times all the transistors will go far into saturation which, I know pull down resistors on the gate would mitigate that but the code explicitly writes the output pins connected to the gate low which should be in a low impedance state. And just recently they flicker like crazy as soon as sda/scl are connected to host. The strange part is, alone or all connected to a breadboard, they function perfectly for extended periods of time (tested for hours). But when I hook them all up they do not.construction- I have used 18awg wire to supply 5v and gnd to all digits. For i2c I am using 1 TP from a cat5e cable and 680ohm pull ups (which gave pretty sharp state transitions for the ~3m of cat5e). The power supply is switching, but offers decently clean dc and is the same one I used on the breadboard when they all worked. For testing, the host is currently setup where it cycles through all 10 values every second, then changes the address to the next digit and repeats. I did have a random ceramic capacitor from vcc to gnd on the Attiny, but then after reading other forum post I put exactly 0.1uF as close as I could but to no avail.I have tried everything to my knowledge and would just like to know what to try next. The power seems clean, the i2c is pretty square given the abilities of my 1970's scope and the 3m of wire, and the circuit works until I hook it all up on my project. I have also lowered the i2c to 25khz to try and combat the wire capacitance at this length. At 3m, the cat5e should still be well under the 400pF limit of i2c (~150-200pF). Attached is a picture of the circuit, a schematic, and the code for the Attiny84. The gate resistors are 330ohm and I used 2n7000 n-mos instead. Any suggestions are greatly appreciated.Code:#include <Wire.h>const int g_arrayTransistors = {0,1,2,3,5,7,8};//pins of transistors for segments A-Gconst byte TRANSISTOR_CONFIG = {{1,1,1,1,1,1,0},{0,1,1,0,0,0,0},{1,1,0,1,1,0,1},{1,1,1,1,0,0,1},{0,1,1,0,0,1,1},{1,0,1,1,0,1,1},{1,0,1,1,1,1,1},{1,1,1,0,0,0,0},{1,1,1,1,1,1,1},{1,1,1,0,0,1,1}};unsigned long g_dutyCycle = 100;unsigned long g_intervalTuple = {0,0};bool g_DisplayOn = true;byte* g_transistorConfig = TRANSISTOR_CONFIG;unsigned long g_phaseShiftTime = 0;byte incomingByte = 0;void setup() {for (int i = 0; i <= 7; i++) {pinMode(g_arrayTransistors, OUTPUT);}Wire.begin(0x15);Wire.setClock(25000);}void updateState(byte incomingByte) {//returns boolean value to prevent anyif (incomingByte == 254) g_DisplayOn = false;else if (incomingByte == 255) g_DisplayOn = true;}void updateTransistors(byte* g_transistorConfig, bool allOff) {for (int i = 0; i < 7; i++) {if (allOff) {digitalWrite(g_arrayTransistors, LOW);} else {digitalWrite(g_arrayTransistors, g_transistorConfig);}}}void updateGlobals(int numBytes) {if (Wire.available() > 0) { //checks data stream for new byte to readincomingByte = (byte) Wire.read(); //if new byte avaliable, assign to byteif (incomingByte >= 0 && incomingByte <= 9) {g_transistorConfig = TRANSISTOR_CONFIG;} else if (incomingByte >= 254 && incomingByte <= 255) { //change the bool variable g_DisplayOnupdateState(incomingByte);} else if (incomingByte >= 100 && incomingByte <= 200) { //pass incomingByte and change the value of unsigned long g_dutyCycleg_dutyCycle = (unsigned long)map(incomingByte, 100, 200, 1, 3999);}}}void loop() {Wire.onReceive(updateGlobals);unsigned long currentTime = micros(); // take current timeif (currentTime >= g_intervalTuple && currentTime <= g_intervalTuple) {//if current time is in the known cycle periodif (currentTime < g_phaseShiftTime && g_DisplayOn) { //in HIGH region //start-end time need to be 0 in setup for this to be false on startupupdateTransistors(g_transistorConfig, false);} else if (currentTime > g_phaseShiftTime || !g_DisplayOn) {//in LOW region, write ALL pins LOWupdateTransistors(g_transistorConfig, true);}} else {// update global interval to this current 4 ms period.g_intervalTuple = currentTime;g_intervalTuple = currentTime + 4000;g_phaseShiftTime = g_intervalTuple + g_dutyCycle;}}

author: ledtester
author_rank: Super Contributor
timestamp: January 01, 2021, 05:29:47 am
content: Does each slave device have pull-up resistors on SDA and SCL? Only one device needs to supply the pull-ups - usually this is relegated to the master device.

author: doodlebob
author_rank: Newbie
timestamp: January 01, 2021, 05:50:38 am
content: I have the pull ups on the master only.

author: ledtester
author_rank: Super Contributor
timestamp: January 01, 2021, 06:44:05 am
content: Initially I thought you were using the 2n3819's, but then I noticed this:QuoteI'm curious how you are limiting current through the LEDs.

author: doodlebob
author_rank: Newbie
timestamp: January 01, 2021, 07:02:49 am
content: I did not want to use resistors so I implemented "software" pwm in the code. I have no way of knowing if I have too much current but they were way to bright even with the resistors on a breadboard so I have the duty cycle at 1% and I know that is no where near enough to burn them.

author: Slh
author_rank: Regular Contributor
timestamp: January 01, 2021, 08:37:01 am
content: Have you disabled the reset pin in software (pin 4)? You might be getting unwanted resets from that pin. Either disable it or add a pull up resistor and a small filter cap (10k and 10n is plenty).The extra capacitance of the bread board might have been enough to filter out any spikes when the LEDs are switching.

author: doodlebob
author_rank: Newbie
timestamp: January 01, 2021, 09:34:53 pm
content: I seemed to have forgotten about the reset pins existence. I have connected a lower value, 3.6k pull up resistor because there is no room for a resistor and capacitor on that pin in my circuit and so far it seems to be working although I have not had time to fully test it. Hopefully that was it and I can report back with a positive result. One thing still puzzles me, the circuits worked fine when only vcc, gnd, sda, and scl were connected to a breadboard and the reset pin was floating. Anyway, thanks for the suggestion!

author: wraper
author_rank: Unknown
timestamp: January 01, 2021, 09:38:50 pm
content: Quote from: doodlebob on January 01, 2021, 07:02:49 amYou cannot do this. You will kill LEDs and MOSFETs this way. It's not like you are allowed to pass unlimited peak current through them. Not to say you don't even know average current. The weirdest part, you added resistors in series to gates, and they really are not required. So you added what's not required and omitted what is required

author: sleemanj
author_rank: Super Contributor
timestamp: January 01, 2021, 10:19:45 pm
content: Quote from: wraper on January 01, 2021, 09:38:50 pmWHile generally speaking, true, it is part, and in the case of fets gate-source voltage dependant. If you are barely at threshold for gate voltage you may be barely passing current.Also note, he's not using mosfets. Those are jfets.

author: wraper
author_rank: Unknown
timestamp: January 01, 2021, 10:24:23 pm
content: Quote from: sleemanj on January 01, 2021, 10:19:45 pmHe is using 2N7000 mosfets. And 5V is completely enough to fully open them.EDIT: and he also connected LEDs in parallel

author: sleemanj
author_rank: Super Contributor
timestamp: January 01, 2021, 11:18:27 pm
content: Quote from: wraper on January 01, 2021, 10:24:23 pmSo I see, schematic doesn't match description

author: doodlebob
author_rank: Newbie
timestamp: January 02, 2021, 05:11:59 am
content: Well after reading some post, reality hit me like a brick and realized even if the average voltage over a time period is within or below the led's foreword voltage, peak current still exist and for a split second the led is still getting 5v and the transistors are also seeing this. At this point I have too much time in this project it would be better just to run these till they blow then start over. Also, yes parallel leds are a horrible idea and I know better but for this project I was more worried about the code than the hardware portion and being able to use the same supply for the chip and the led's was paramount. The gate resistors were not originally there and I did not think I needed them, but after hooking up more than 1 led per transistor , it would go into saturation without them. I am sorry about the schematic. I tried for about 1hr to make a 2n7000 in my own eagle library but after loosing a schematic to a blue screen I did not care enough to try again. So far, ensuring the capacitor was 0.1uF and the reset pull up resistor has done the trick and they are working fine now. Thanks to everyone who pointed out my ignorance's. The only way to make this correctly would be for every bank of led's to have a CC driver and that would mean 56 CC drivers + the transistors and would bring the cost and complexity up an order of magnitude.

author: Dabbot
author_rank: Regular Contributor
timestamp: January 02, 2021, 06:00:11 am
content: Quote from: doodlebob on January 02, 2021, 05:11:59 amNo need for CC driver madness for something like this. Just give each LED its own resistor. Resistors are cheap enough.Then get rid of the discrete transistors and their gate resistors by using a ULN2003.

author: doodlebob
author_rank: Newbie
timestamp: January 02, 2021, 07:18:09 am
content: The ULN2003 would be perfect for this project. The only reason I tried to not used series resistors is the power dissipation. At full brightness I would have 9 watts of heat dissipation from the resistors alone, not to mention the massive efficiency loss. This project is intended to be powered from a battery so 22.4 watts of total power draw would be way to much. Thanks for the help though, I think this project just needs a complete redesign once it fails.

author: ledtester
author_rank: Super Contributor
timestamp: January 02, 2021, 07:28:33 am
content: QuoteLook into modern high-efficiency LEDs. They can achieve adequate brightness at just a few milliamps of current.

author: Dabbot
author_rank: Regular Contributor
timestamp: January 02, 2021, 07:32:25 am
content: Quote from: doodlebob on January 02, 2021, 07:18:09 amWell, judging by the picture, you can cut that in half right away by placing each LED pair in series, giving you two pairs for each segment.

author: Nominal Animal
author_rank: Super Contributor
timestamp: January 02, 2021, 08:38:49 pm
content: Quote from: doodlebob on January 02, 2021, 05:11:59 amYou could use say a MAX6968 8-channel led driver per digit, daisy-chain the digits using four wires between each digit, and a control ATtiny84 that interfaces between I2C and the four-wire protocol used by the MAX6968.

author: doodlebob
author_rank: Newbie
timestamp: January 02, 2021, 11:05:11 pm
content: After thinking on it I have decided to put 150ohm resistors in series with each row of leds to limit the current to a max of 13mA. I did not want to loose the ability of having them driven at full brightness but after thinking, I will never turn the duty cycle past 5% so there is no reason to try and preserve that functionality. Even with 150ohm resistors at 1% duty cycle they are barely comfortable to look at and at this level the power dissipation from the resistors is almost non existent. I should have put them in series but these will stay parallel for this project. I tried to do all of this in 2 weeks and it was outside of my capabilities, but after sinking around 130hr into this I could not sleep knowing that at any second the led's or fets would fail. I have successfully found a few different ways to not properly implement this.

author: ledtester
author_rank: Super Contributor
timestamp: January 03, 2021, 12:11:48 am
content: I think the most difficult part of LED lighting is creating a good diffusion of the light.As an example, here's one guy's build of a giant 7-segment display:(starting at 1:50)https://youtu.be/WUU8AQsf2Zw?t=1m50s

author: doodlebob
author_rank: Newbie
timestamp: January 03, 2021, 06:34:25 pm
content: Those 7 segments make mine look so tiny. That is one thing I thought about doing except with clear 3d printer filament and on a smaller scale. I could still print some simple covers that snap onto the existing leds to try and diffuse them but you do need distance, much like lenses. I still like the idea that each digit of the display has the on board computing but this project really made me appreciate pcb's and smd components. Thanks to all for the helpful information and happy new years.