Electronics > Projects, Designs, and Technical Stuff

Borderlands style jewelry box research thread

<< < (9/17) > >>

Youkai:
Arg. Looking at the Arduino TLC library it seems that you can't change the pin numbers used. Which means I can't change the pin numbers for the Pro Micro. Sparkfun does have a library for their breakout but I'm not sure if that will work. I guess with this and the servo issue I'm back to using the UNO as my microcontroller.

EDIT: Well hell. The wiring diagram for the TLC library does not have configurable pins and connects to 4 PWM pins. Maybe a different library only uses 3? I'm confused.

EDIT 2: I guess I can change the pin numbers if I edit the library files. But I don't know which ones are required to be PWM pins so I can't safely change them. I assume all 4 that are assigned to PWM pins must be. Otherwise why would the developer of the library use up a PWM pin?

exuvo:
You could ignore the arduino PWM library and configure the PWM peripheral yourself. Also never look for reason in those libraries, there is little to be found.
Find the datasheet for the microcontroller, the sections of interest are the Timers and what pins they allow for output compare / PWM. Each timer should have 2 output pins that are suitable for PWM. Usually you set the pin for output mode like normal, setup the TCCRx registers with a suitable output compare mode and prescaler (for frequency) and load OCRx with a value for length of pulse.

You might need to be careful with timer 0 as i think arduino likes to use it for the time keeping functions. If you wont be using those functions you can re-configure the timer for your own use or try to work with whatever frequency it is already running at.
The difficult part is usally finding a picture that shows what arbitary number an arduino pin is mapped to in the hardware, ex arduino pin 5 to PORTA bit 6.

Some example code from one of my ATmega328 projects if you find it helpful. Comments might be incorrect.

--- Code: ---void TimersInit() {
GTCCR = _BV(TSM) | _BV(PSR10); // pause timers
// OCR0A = 0;

//timer 0 - CTC toggle - output pulse 500kHz
TCCR0A = _BV(WGM01);

//timer 0 - prescale factor 8 - 1MHz
TCCR0B = _BV(CS01);

//122 full 4096 cycles / s


OCR1A = 4096*2+1;//timer 0 takes 2 cycles for each pulse, first pulse is ignored. +1 to edge align with timer 0
// OCR1B = 0;

//timer 1 - Fast PWM
TCCR1A = _BV(WGM11) | _BV(WGM10);

//timer 1 - prescale factor 8
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS11);

//122Hz full cycles

GTCCR = 0; // resume timers
}

//timer compare to pin
#define TIMER0A 6
#define TIMER0B 5
#define TIMER1A 9
#define TIMER1B 10
#define TIMER2A 11
#define TIMER2B 3

void PWM(uint8_t pin, uint8_t val){
/**
* If PWM is in fast mode val == 0 does not work
* if (val == 0) {
*   PORT &= ~_BV(PIN);
* } else {
*/

if (pin == TIMER1A) {
TCCR1A |= _BV(COM1A1);
// set PWM duty
OCR1A = val;
} else if (pin == TIMER1B) {
TCCR1A |= _BV(COM1B1);
// set PWM duty
OCR1B = val;
} else if (pin == TIMER0A) {
TCCR0A |= _BV(COM0A1);
// set PWM duty
OCR0A = val;
} else if (pin == TIMER0B) {
TCCR0A |= _BV(COM0B1);
// set PWM duty
OCR0B = val;
} else if (pin == TIMER2A) {
TCCR2A |= _BV(COM2A1);
// set PWM duty
OCR2A = val;
} else if (pin == TIMER2B) {
TCCR2A |= _BV(COM2B1);
// set PWM duty
OCR2B = val;
} else {
extern void error(uint8_t errorCode);
error(12);
}
}

--- End code ---

Ian.M:
Another option would be to eliminate the TLC5940 and instead use smart RGB LEDs, e.g. WS2812 (aka: Adafruit Neopixels) or APA102 (aka: Adafruit Dotstar).  There's an Arduino Neopixel library that handles the tightly timed WS2812 single wire interface, or if you use APA102 based LEDs, its a two wire SPI interface with no timing constraints, and yes, there is an Arduino library for it.

Neopixels don't play well with background interrupts, but for a limited string of them, it would be possible to wait for a safe time in the servo frame to call  pixels.show() to update them without causing servo jitter.

Youkai:
This one would probably work perfectly for my needs: https://www.adafruit.com/product/1426

So if I were to do this I would use 5 total PWM pins? 1 each for the 2 LED strips and 1 each for the 3 servos? Actually this https://learn.adafruit.com/adafruit-neopixel-uberguide/basic-connections says "any digital pin" can be the data pin so I wouldn't even need to use a PWM pin necessarily it seems. Yeah I'm just gonna do this. It will make the wiring much easier. Oh also this NeoPixel Stick needs a 5v power supply so I can take the transistors out too! happy days.

I'm not sure I understand the comment about background interrupts. Do you mean like if I were to use attachInterrupt() from the Arduino library? I wasn't planning on using that in my code so I think this won't be an issue.

EDIT: Ordered the RGBW one instead since I'm going to use one to light the inside when open so having a true white option would be good. https://www.adafruit.com/product/2869

Ian.M:
The problem is the servo library uses interrupts, and if one occurs during pixels.show(), that would corrupt the data transfer to the LEDs.  Therefore the show() method disables interrupts while it is outputting the pixel data.   This will make any servo jitter if its servo pulse edge is due to occur while show() is executing.   To avoid that, before calling show(), you need to poll the timer controlling the servos to check if its past the end of the last servo pulse and is waiting for the end of the 20ms servo refresh frame.

Navigation

[0] Message Index

[#] Next page

[*] Previous page

There was an error while thanking
Thanking...
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod