Show Posts
|
|
Pages: [1] 2 3
|
|
1
|
Using Arduino / LEDs and Multiplexing / Re: TLC5940 sometimes goes full instead of blank
|
on: March 12, 2013, 04:30:37 pm
|
Try setting the blank pin as an INPUT.
But I'm still calling Tlc.clear() and Tlc.update(), right? So it shouldn't matter. Whatever. I did that, and it was the same as before: issue fixed when the pot is at full, but at anything else the lights flickered every fourth wake. Sometimes it flickered even when the pot was full. It stopped flickering when I moved my hand near the GSCLK pin, so I figured it wasn't initializing correctly (though why every fourth time, I don't know). So I cleared TCCR1A and TCCR1B before calling Tlc.init() after wake, and everything is fine now! It looks like several of my issues along the way might have been caused by a corrupted TIMER1. Maybe. It also works if I keep D10 as an output and write it HIGH, but just to be safe I'll make it an input as you suggested. Thanks for helping me.
|
|
|
|
|
2
|
Using Arduino / LEDs and Multiplexing / Re: TLC5940 sometimes goes full instead of blank
|
on: March 11, 2013, 05:04:05 pm
|
The TLC5940 receives its clock signal from the 328p. [...] At low brightness there's more chance of the LEDs being off (they spend more time 'off' in the PWM cycle).
Makes perfect sense! Except... 1) I'm clearing and updating the TLC before sleep, 2) I'm writing BLANK (pin 10) HIGH before sleep, and 3) there's a pull-up from BLANK to Vcc. On a whim, I tried writing D11 HIGH on sleep instead of D10. Instead of never working, it now works every fourth try. Writing D9 high instead makes it sporadically work for a few pushes in a row. (I have it wired up exactly as shown in the "Basic Use" example from the Tlc5940 library.) Writing D3 (GSCLK) HIGH before sleep (and the re-calling Tlc.init() after wake) makes it work great... but if the pot's not at full, it occasionally blinks instead of being steady when it wakes.
|
|
|
|
|
3
|
Using Arduino / LEDs and Multiplexing / TLC5940 sometimes goes full instead of blank
|
on: March 10, 2013, 08:18:22 pm
|
(Not sure if this should go in Programming Questions. Feel free to move it.) I have a binary clock. I'm using a TLC to control the LEDs, and Alex Leone's Tlc5940 library. The µC is a standalone 328p (internal clock) reading from a DS1337, which is itself clocked by a TCXO. (Gotta love free samples.) There are two ways to affect the LEDs. One is a pot: brightLevel = analogRead(potPin) / 4; //convert for gamma correct (included in library) Tlc.setGC(9, brightLevel);} else {Tlc.setGC(9,0); //for example The other is a pin-change interrupt that actually sleeps the chip: ISR(PCINT2_vect) { if (justSlept == 1) {} //don't mess things up if we're in the middle of/just woke up from sleeping else {lightsOn = 0;} //otherwise, set the sleep-now flag } void sleepNow() { justSlept = 1; Tlc.clear(); Tlc.update(); digitalWrite(10, HIGH); //this is redundant (there is a pull-up from BLANK to Vcc) ADCSRA |= (0<<ADEN); //turn of ADC to reduce power consumption sleep_enable(); delay(150); //debounce; otherwise we wake immediately after sleep sei(); MCUCR = _BV (BODS) | _BV (BODSE); // turn on brown-out enable select MCUCR = _BV (BODS); // this must be done within 4 clock cycles of above sleep_cpu (); // sleep within 3 clock cycles of above sleep_disable(); //now we've just woken up (button push triggers PCint) lightsOn = 1; //set sleep-now flag OFF lastToggle = millis(); ADCSRA |= (1<<ADEN); //turn ADC back on }
void loop() { int timeSinceToggle = millis() - lastToggle; if (timeSinceToggle >= 200) justSlept = 0; //debounce if (lightsOn == 0 || timeSinceToggle >= 1800000) sleepNow(); //if the sleep-now flag is set, or if it's been half an hour, sleep else { //here the code reads the pot, gets time from the RTC, sets the LEDs, sees if the time is being set externally... } The code works beautifully, for the most part. Current into the 7805 drops from ~120mA (pot all the way down) to ~40mA asleep. However, whenever the pot is at full-on, the LEDs go full-bright instead of full-off when the 328p sleeps. (Not all of them, just the ones lit at the time.) Current drops, but certainly not all the way (as the lights are still on). The pot doesn't affect the brightness, and setting the time doesn't do anything—again, because the 328p is asleep. But it must still be driving BLANK low, or something. The problem doesn't go away until I turn the pot down, at which point the lights turn off as expected. This sometimes happens when the pot isn't at full, too. Instead of going off, the LEDs go full-bright. But it doesn't happen as often. Any ideas what might be causing this?
|
|
|
|
|
4
|
Using Arduino / LEDs and Multiplexing / Re: A really fast software PWM library
|
on: February 05, 2013, 06:46:26 pm
|
Hi Palatis (or anyone who wants to help), I looked at the other two libraries you mentioned before finding yours, and I think yours is better (more efficient and uses TIMER1 instead of TIMER2, which I'm clocking asynchronously for an RTC). But! I have a problem. I'm making a modified version of Daniel Andrade's binary clock. What he does is strip the HH:MM into its separate digits, and decide whether each LED turns on or not depending on what the digit is. An exemplary line: if(munit == 4 || munit == 5 || munit == 6 || munit == 7) {digitalWrite(3, HIGH);} else {digitalWrite(3, LOW);} What I'm doing is using your PWM to allow me to dim the LEDs, like so: if(munit == 4 || munit == 5 || munit == 6 || munit == 7) {SoftPWM.set(3, brightLevel);} else {digitalWrite(3, LOW);} //brightLevel is the divided analogRead of a pot But when I do this, the LEDs that should be off stay on, and don't respond to the pot—as if they've been written HIGH! "Huh," I think to myself. "Must be something funny about his code. I'll just do this, then:" if(munit == 4 || munit == 5 || munit == 6 || munit == 7) {SoftPWM.set(3, brightLevel);} else {softPWM.set(3, 0);} And when I do that, sure enough, the LEDs that should be off stay off. But the window for brightLevel shrinks almost completely: the LEDs are full-on for most of the dial, then near-instantly switch to full-off. There are only a few degrees in which they're actually dimmed. Any ideas as to what's going on, and how I can fix it? Thanks!
|
|
|
|
|
7
|
Using Arduino / Programming Questions / Re: Can't find old topic on clock compensation
|
on: February 03, 2013, 08:50:06 pm
|
#include <avr/sleep.h> #include <avr/power.h>
const byte tick = 11;
// interrupt on Timer 2 compare "A" completion - does nothing ISR(TIMER2_COMPA_vect) { digitalWrite (tick, ! digitalRead (tick)); }
void setup() { pinMode (tick, OUTPUT); // clock input to timer 2 from XTAL1/XTAL2 ASSR = _BV (AS2);
// set up timer 2 to count up to 32 * 1024 (32768) TCCR2A = _BV (WGM21); // CTC TCCR2B = _BV (CS20) | _BV (CS21) | _BV (CS22); // Prescaler of 1024 OCR2A = 15; // count to 32 (zero-relative)
// enable timer interrupts TIMSK2 |= _BV (OCIE2A); /* // disable ADC ADCSRA = 0; // turn off everything we can power_adc_disable (); power_spi_disable(); power_twi_disable(); power_timer0_disable(); power_timer1_disable(); power_usart0_disable(); // full power-down doesn't respond to Timer 2 set_sleep_mode (SLEEP_MODE_PWR_SAVE); // get ready ... sleep_enable(); */ } // end of setup
void loop() { /* // turn off brown-out enable in software MCUCR = _BV (BODS) | _BV (BODSE); MCUCR = _BV (BODS); // sleep, finally! sleep_cpu ();
// we awoke! pulse the clock hand digitalWrite (tick, ! digitalRead (tick)); */ } // end of loop
Always blinks at 15.99 Hz, regardless of ACR2A. Thanks!
|
|
|
|
|
8
|
Using Arduino / Programming Questions / Re: Can't find old topic on clock compensation
|
on: February 03, 2013, 08:09:54 pm
|
Just to prove it to myself, I made this amended sketch:
Okay, I am seriously upset/confused right now. When I use your code (with the EMPTY_INTERRUPT), changing the value of OCR2A changes the frequency of the blinking. As expected. If I change EMPTY_INTERRUPT to an ISR, move the digitalWrite up into the ISR, and comment out all the sleepy-stuff, changing OCR2A has no effect at all. Zip. Nada. Using the exact same TCCR2A/B values. The frequency is always the base frequency of the prescaler, as if OCR2A is 0. What am I not seeing here?
|
|
|
|
|
10
|
Using Arduino / Programming Questions / Re: Can't find old topic on clock compensation
|
on: January 31, 2013, 03:47:26 pm
|
What do you mean by "clicking something"? If the clicking thing is on the output pin, it will click, right?
Sorry, I'm not being clear. I'm working with a tweaked version of Daniel Andrade's binary clock ( direct link to code), so the "click" I was talking about was setting the seconds (minutes, half-seconds, eight-seconds, whatever) counter ahead by one. Not a physical click like the second hand on a watch. Basically, the code keeps track of hours and minutes (and seconds, though it doesn't display them). Then it strips HH:MM into H, H, M, M and figures out which LEDs to turn on based on that. So the chip needs to be awake to set/check the seconds and change the LEDs, and also if the hour/minute-set buttons are pushed (which I'll use an external interrupt for). void loop () { go_to_sleep (); click_clock_hands (); }
If I'm reading this right, that makes the chip 1) go to sleep until the interrupt fires, 2) tick the time, and 3) repeat, yes?
|
|
|
|
|
11
|
Using Arduino / Programming Questions / Re: Can't find old topic on clock compensation
|
on: January 31, 2013, 08:34:51 am
|
If you change the prescaler then it toggles every 500 mS giving a frequency of 1 Hz.
Right, but it's still toggling an output pin, not clicking something, right? I could set up some code to monitor that pin and second++ every tick or two ticks or whatever, but why would I do that when I have the ISR? Besides, eventually I want to sleep the chip and have the ISR wake it every second (or five seconds). Not sure if that's going to happen, but it's the goal.
|
|
|
|
|
12
|
Using Arduino / Programming Questions / Re: Can't find old topic on clock compensation
|
on: January 30, 2013, 10:18:51 pm
|
|
Hoo boy! Quite the setup you've got there.
Well, curiosity kills the chip. I have discovered that bending the pins three times is one time too many, and now I have a perfectly working µC with no XTAL/TOSC pins. Maybe I'll see if I can come up with some non-time-critical project sometime. I'll try out your code when the new ones arrive!
|
|
|
|
|
14
|
Using Arduino / Programming Questions / Re: Can't find old topic on clock compensation
|
on: January 30, 2013, 09:07:01 pm
|
Get the timer to toggle a pin, don't rely on an ISR to do it.
What? I thought the ISR was the manifestation of the timer. Are you saying something like this? if (TCNT2 = 3){ //toggle pin } Because the reason I wanted an interrupt in the first place is so I can sleep the chip in the meantime. I don't know if it's really worth the 17 mA, especially when there'll be lots of LEDs on anyway. But that was my idea.
|
|
|
|
|
15
|
Using Arduino / Programming Questions / Re: Can't find old topic on clock compensation
|
on: January 30, 2013, 08:51:21 pm
|
|
Well, with the original code (using the toggle) I find that OCR=1 generates 1/2 of 16384Hz (interestingly, so does OCR=0). At least, it should. I'm reading 8190, which is ~250ppm off—way more than the ~40 expected from the temperature. That could well be errors in the DMM—I don't really see what else, unless the crystal is picking up parasitic capacitance through the air from the breadboard rails underneath it.
That translates to 21 seconds per day slow, if I define a second as 8292 interrupts. (Or I could just code it as 8190, and assume that my meter isn't off.) That's not ideal, but it's not the second-every-five-minutes loss I was having before.
One thing I've determined: The calculator I linked to earlier rounds the answer it spits out—when I say I want 4 kHz, for example, it tells me I can use no prescaler and OCR=8 and have 0% error, but the fact is I will have error because everything's in factors of two. Nominal 8 kHz is actually 8192 Hz. This is possibly why the clock was so slow earlier.
|
|
|
|
|