Friday, December 30, 2022

0000 0000 1011 0110

Mailbag #26

A collection of very useful and completely useless items coming in from 中國.

I really need to start running some of these late night decisions past a disinterested observer! 😬



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..



Friday, December 16, 2022

0000 0000 1011 0100

A mosfet and a string of LEDs

I have previously confessed that I did not manage organise my Christmas lights in time this year. Following Mr PileOfStuff's example I should have grabbed an ESPixelStick, downloaded software, hooked it all up to my lights and network, and then kicked back with some eggnog (whatever that is) and enjoyed the festive season.

But no - my extreme laziness and disorganisation sees me instead just grabbing an ESP8266 (ESP-01 version) from the buckets, loading up the old (but stable) V3.2 ESPixelStick software, and then hooking up the WS2811 lights and adding power. The result? Fizzing and spluttering nonsense!

After a fair bit of head scratching and reading I came to the realisation that the 3.3V data signal coming out of the ESP8266 was not talking to the 5V tolerant WS2811 chip. The voltage mismatch had resulted in illogical confusion. Thus began a bit of a deep dive into voltage level shifting.

Thus, following on from last week's blog and video about voltage level shifting for data lines, I did some more experimentation with various chips, modules and circuits and eventually settled on a very common solution as shown in the following diagram. Low voltage (LV) is 3.3V and High Voltage (HV) is 5V in my case. I will only need one way data transmission across this level shifter, but it does in fact work both ways.

There are a lot of mosfet transistors that would admirably perform the switching, I settled on the BS170 as per the diagram - I have a few and it seemed most likely to easily meet the 800(k)Hz data switching speed required of the circuit. In fact it can switch well into the MHz range.

The commercial version is almost always based on a BSS138 mosfet, and as well I tried the 2N7000 with success.

I also upgraded the ESP-01 from 1Mb to 4Mb as has been done before, solely to try and squeeze the new version of the ESPixelStick software onto the device.

I successfully tested the hardware and software with the level shifter doing the translation, and also tried different software (WLED). Despite my initial bumblings, it seems that Christmas will be well served by festive lights after all!



Friday, December 9, 2022

0000 0000 1011 0011

Shifting voltages (3.3V to 5V)

Shamed by PileOfStuff into finally upgrading my Christmas lights, I ran into an all too familiar problem.

Kent sensibly acquired and continues to use the ESPixelStick as his hardware/software for his lights, but due to my laziness and disorganisation I would not be able to get one into the country in time for the current festive season.

Also - due to a late night buying spree, I happen to have a lot of ESP8266 (ESP-01s versions).

Furthermore, I have in the past desoldered the paltry 1Mb flash and upgraded the memory to 4Mb so a LED loving webserver should be possible (more on this in a later post).

Amazingly - I managed to get all of the hardware and software sorted and then...major disappointment! The data output from the ESP8266 (3.3V) is insufficient for the WS2811 chip (5V) to be happy.

A few fizzly lights later and a bit of looking about on the interwebs and I was down the "level shift" rabbithole.

This blog post and video is about the first part of this journey. I started with a CMOS chip (the CD4081) with the intention of using it to level up the signal voltage to 5V.


It didn't work as expected! A really big rabbithole later I found out that CMOS chips usually need a 3.5V minimum for "High" to be registered, and we have 3.3V coming out of the ESP8266 - whoops!

Therefore, halfway through the attempt I swapped out the CD4081 CMOS IC for a TTL chip, the SN74HCT14N which is a hex inverter.

TTL chips (at least this one) describe a minimum voltage for registering a "HIGH" as 2.7V, well under the 3.3V that is arriving at the GPIO. 

A hex inverter! Hex as in "evil curse" because I've had to use these inverters so many times now - they just keep haunting me.


Wiring the whole thing up worked a treat - and the level shifting was done. I was able to start with a pulse from a 3.3V source and output a 5V signal.

Part Two of this blog and video will be using this new found level shifting knowledge to connect a 3.3V data line to the 5V LEDs and trying out a few options. Stay tuned!


 




Thursday, December 1, 2022

0000 0000 1011 0010

Mailbag #25 (including Pi(e)s)

This week there is much to be found in the mailbox, including some locally sourced Raspberry Pi Picos - watch out soon for some WiFi enabled Picos currently in the air flying down to Tasmania.

In the meantime, enjoy the video.