Friday, December 23, 2022

0000 0000 1011 0101

PCBWay and little lights

For a few years now I've been using the 5050 "three-in-one" LEDs to provide nice gentle yellow night time light. I have previously posted a blog and video about these LEDs.

Recently I have been thinking a little too much about the next improvement to this longtime and ongoing project. It occurred to me that this combined LED is missing two advantages of a real flame.

1. The LEDs are available in either RGB (not very lifelike) or a single colour (such as yellow in my case)

2. The LEDs are crowded around a fairly tight radius (around 1.7mm) which makes it almost "pin point"

Also I thought it would be good to have an integrated minimum resistance protection component as well as a space for a potentiometer to regulate light levels.

The resultant and rather hastily designed board was sent out to PCBWay and in particular a big shout out to Elaine who very generously came onboard to manufacture and ship the PCBs.

They arrived really quickly because Elaine sent them DHL which was hugely expensive!

Before racing along to the candle project, I wanted to test the LED PCB in a more familiar environment (or so I thought). I wanted to build on an old project which used a single SMD LED.

The simple extension was to code for three lights and a temperature scale to give greater accuracy when looking out the window.

/*
   LM35 RGB solar light temperature monitor
   OneCircuit:
   https://www.youtube.com/c/onecircuit-as/videos
   https://onecircuit.blogspot.com/

   pin PB3 used as VCC for LM35
   pin A2 used as analog input
   pins PB0-2 used as LED outputs

   Device: ATtiny13A
                ____________
               /           |
              | RESET  VCC | VCC
  LM35-switch | PB3    PB2 | RLED
           A2 | PB4    PB1 | BLED
              | GND    PB0 | GLED
              |____________|

   Fri 23 Dec 2022 10:58:44 AEDT
*/

#include <avr/sleep.h>
#define sensorPin A2
#define LM35VCC PB3
#define RLED 0b00000100
#define BLED 0b00000010
#define GLED 0b00000001

void setup() {
  DDRB = 0b00001111;
  PORTB = 0b00000000;
  // start up LED dancing!
  blinkme(RLED);
  blinkme(RLED);
  blinkme(BLED);
  blinkme(BLED);
  blinkme(GLED);
  blinkme(GLED);
}

ISR(WDT_vect) { // wake up!
}

void snooze(uint8_t cycles, uint8_t howlong) {
  // sleep preparation
  WDTCR = howlong;
  ADCSRA &= ~(1 << ADEN);
  ACSR |= (1 << ACD);
  cli();
  BODCR = (1 << BODSE) | (1 << BODS);
  BODCR = (1 << BODS);
  sei();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();

  // sleep now
  for (cycles; cycles > 0; cycles--) {
    sleep_mode();
  }

  sleep_disable();        // waking up
  ADCSRA |= (1 << ADEN);  // turn on ADC
  ACSR = (0 << ACD);      // Turn on Analog comparator.
  delay(10);              // take a breath
}

// apparently needed before analogRead in this case
void adc_setup (void)
{
  ADMUX = (2 << MUX0);
  ADMUX |= (0 << ADLAR);
  ADCSRA |= (1 << ADPS1) | (1 << ADPS0) | (1 << ADEN);
}

// blinking routine
void blinkme(uint8_t whichcolour) {
  PORTB = whichcolour;    // turn on GLED
  snooze(1, 0b01000011); // 1x64 ms sleep
  PORTB = 0b00000000;    // black out
  snooze(1, 0b01000100); // 1x250 ms sleep
}

void loop() {
  snooze(1, 0b01100000); // 1x4 second delay
  adc_setup();
  digitalWrite(LM35VCC, HIGH);
  delay(100);            // settle LM35

  long int temperature = analogRead(sensorPin);
  temperature = ((temperature * 449L) / 1023L);

  digitalWrite(LM35VCC, LOW);

  // analyse result
  if (temperature > 23) {
    blinkme(RLED);
    blinkme(RLED);
    blinkme(RLED);
  }
  else if (temperature > 19) {
    blinkme(RLED);
    blinkme(RLED);
  }
  else if (temperature > 17) {
    blinkme(RLED);
    blinkme(GLED);
  }
  else if (temperature > 15) {
    blinkme(RLED);
    blinkme(BLED);
  }
  else if (temperature > 13) {
    blinkme(GLED);
    blinkme(RLED);
  }
  else if (temperature > 11 ) {
    blinkme(GLED);
    blinkme(GLED);
  }
  else if (temperature > 9) {
    blinkme(GLED);
    blinkme(BLED);
  }
  else if (temperature > 7) {
    blinkme(BLED);
    blinkme(RLED);
  }
  else if (temperature > 5) {
    blinkme(BLED);
    blinkme(GLED);
  }
  else if (temperature > 3) {
    blinkme(BLED);
    blinkme(BLED);
  }
  else {
    blinkme(BLED);
    blinkme(BLED);
    blinkme(BLED);
  }
}

Sadly there was a huge rabbit hole (more like an underground labyrinth) which developed over some fake LM35 ICs, a problematic LM335 sidetrack involving floating point calculation approximations, and a heap of useful but frustrating problems which makes this a very long, but hopefully interesting video. 

Again, thank you to PCBWay who were incredibly generous in their provision of the PCBs featured, the subsequent freight and of course a heap of lovely s.w.a.g.

Enjoy the (long) video..



No comments:

Post a Comment