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:
Code:
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:
Code:
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:
Code:
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:
Code:
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:"
Code:
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!
5  Using Arduino / Programming Questions / Re: Can't find old topic on clock compensation on: February 03, 2013, 09:36:47 pm
Well! I tried moving the OCR2A line up; nothing changed. I added the TCCR2A = 0 and TCCR2B = 0 lines at the top and it works! Which is strange, because in other non-working sketches I've tried it hasn't worked. Must've been a combination of that and moving the OCR2A line.
6  Using Arduino / Programming Questions / Re: Can't find old topic on clock compensation on: February 03, 2013, 09:23:52 pm
I've still got the problem. Changing the prescaler changes the frequency; changing OCR2A changes absolutely nothing. I guess there's something screwy inside the chip, and I'll just work around that in my code.
7  Using Arduino / Programming Questions / Re: Can't find old topic on clock compensation on: February 03, 2013, 08:50:06 pm
Code:

#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?
9  Using Arduino / Programming Questions / Re: LED brightness control on: January 31, 2013, 04:07:15 pm
Don't know what pulling resistor is
What exactly is it ?

http://en.wikipedia.org/wiki/Pull-up_resistor
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).

Code:
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!
13  Using Arduino / Programming Questions / Re: Can't find old topic on clock compensation on: January 30, 2013, 09:32:18 pm
Neat! Works for me too. But this is only for crystal testing, right? The long-term goal, after all, is to tick a counter for the clock.
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?
Code:
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.
Pages: [1] 2 3