The 3D flame in a vase
I was at an antique store recently, just browsing, not looking for anything in particular when I spied a lovely crystal vase - a steal at AUD$15.
Straight away I thought of the reflective and refractive possibilities should I shoehorn in a small solar panel and the stable joule thief (padauk version) together with the new "3D" LED PCB.
After soldering it all up and blasting the code onto the PFS154, I glued the lot into the vase and I'm happy to report that the light provided at night is quite lovely!
/* Candle with Three PWM Pseudo-random flickering to simulate a candle. Output is via 3xPWM channels, variables can be changed to alter the simulation Tue 17 Jan 2023 13:50:35 AEDT */ #include <stdint.h> #include <stdlib.h> #include "../device.h" #include "../easy-pdk/calibrate.h" #include "../auto_sysclock.h" #include "../delay.h" #include <stdbool.h> #define LED4_BIT 4 #define LED0_BIT 0 #define LED3_BIT 3 uint16_t myrand = 2901; // happy birthday uint8_t slowcounter = 0; uint8_t medcounter = 0; uint8_t fastcounter = 0; uint8_t slowstart = 0; uint8_t slowend = 0; uint8_t medstart = 0; uint8_t medend = 0; uint8_t faststart = 0; uint8_t fastend = 0; uint8_t faster = 0; uint8_t waveslow[] = {20, 30, 70, 100}; uint8_t wavemed[] = {25, 40, 100, 120}; uint8_t wavefast[] = {20, 30, 120, 140}; bool fastup = true; bool slowup = true; bool medup = true; void mydelay(uint8_t counter) { for (uint8_t thiscount = 0; thiscount <= counter; thiscount++) { _delay_us(1); } } uint16_t gimmerand(uint16_t small, uint16_t big) { myrand ^= (myrand << 13); myrand ^= (myrand >> 9); myrand ^= (myrand << 7); if (abs(myrand) % 13 == 0) { myrand = myrand - 23; } if (abs(myrand) % 17 == 0) { myrand = myrand + 11; } return abs(myrand) % 23 * (big - small) / 23 + small; } void getnewslow() { slowstart = gimmerand(waveslow[0], waveslow[1]); slowend = gimmerand(waveslow[2], waveslow[3]); } void getnewmed() { medstart = gimmerand(wavemed[0], wavemed[1]); medend = gimmerand(wavemed[2], wavemed[3]); } void getnewfast() { faststart = gimmerand(wavefast[0], wavefast[1]); fastend = gimmerand(wavefast[2], wavefast[3]); faster = gimmerand(2, 6); } // Main program void main() { PAC |= (1 << LED4_BIT) | (1 << LED0_BIT) | (1 << LED3_BIT); // see datasheet PWMG1DTL = 0x00; PWMG1DTH = 0x00; PWMG1CUBL = 0xff; PWMG1CUBH = 0xff; PWMG1C = 0b10100111; PWMG1S = 0b00000000; PWMG0DTL = 0x00; PWMG0DTH = 0x00; PWMG0CUBL = 0xff; PWMG0CUBH = 0xff; PWMG0C = 0b10100111; PWMG0S = 0b00000000; PWMG2DTL = 0x00; PWMG2DTH = 0x00; PWMG2CUBL = 0xff; PWMG2CUBH = 0xff; PWMG2C = 0b10100111; PWMG2S = 0b00000000; getnewfast(); getnewslow(); getnewmed(); slowcounter = slowstart; fastcounter = faststart; medcounter = medstart; // Main processing loop while (1) { // ramp up slow if (slowup) { slowcounter++; if (slowcounter > slowend) { // ramp finished so switch boolean slowup = !slowup; } } else { // ramp down slow slowcounter--; if (slowcounter < slowstart) { // ramp finished so switch boolean slowup = !slowup; getnewslow(); } } // ramp up med if (medup) { medcounter++; if (medcounter > medend) { // ramp finished so switch boolean medup = !medup; } } else { // ramp down med medcounter--; if (medcounter < medstart) { // ramp finished so switch boolean medup = !medup; getnewmed(); } } // ramp up fast if (fastup) { fastcounter = fastcounter + faster; if (fastcounter > fastend) { // ramp finished so switch boolean fastup = !fastup; } } else { // ramp down fast fastcounter = fastcounter - faster; if (fastcounter < faststart) { // ramp finished so switch boolean fastup = !fastup; getnewfast(); } } // delay + a re-purposed random for ramp speeds mydelay(15 + faster); PWMG1DTL = slowcounter & 255; PWMG1DTH = slowcounter; PWMG0DTL = fastcounter & 255; PWMG0DTH = fastcounter; PWMG2DTL = medcounter & 255; PWMG2DTH = medcounter; } } // Startup code - Setup/calibrate system clock unsigned char _sdcc_external_startup(void) { CLKMD = CLKMD_ILRC | CLKMD_ENABLE_ILRC | CLKMD_ENABLE_IHRC; CLKMD = CLKMD_ILRC | CLKMD_ENABLE_ILRC; PDK_SET_SYSCLOCK(SYSCLOCK_ILRC); EASY_PDK_CALIBRATE_ILRC(50000, 4000); return 0; }
Judge the result for yourself - but this one has been chugging away at night time for a few weeks now and is a bit of a hit with the executive!
No comments:
Post a Comment