Thursday, April 27, 2023

0000 0000 1100 0111

Two out of three ain't bad

Recently an LED in the house went dark, and usually I'd just throw it out and replace it. This time I thought it was a bit rude as the bulb is nominally rated 30000 hours and it had only been in for around 100 hours.


Two possibilities:

1. The bulb was not up to spec

2. The variations in AC voltage at our place was too much for it

Either way I could see some clear marks from a possible short, and so I wanted to open it up and take a look.

The result is a little bit of a boring video, but nonetheless "illuminating". Also, breaking into the device was a bit of a laugh.


Friday, April 21, 2023

0000 0000 1100 0110

The Dirty Dozen - Part Four - unreachable exotica

I saw a beautiful shiny bauble in the online shop that turned out to be unobtainium! 

Recently Great Scott did an AliExpress based video where he was trawling through Chinese datasheets trying to gain access to a particular piece of hardware.

Oh, Great Scott - how much time I have wasted in this exact same situation!

Case in point, a lovely looking Air105 based module. Would I have bought it in hindsight? Yes! Who doesn't like unobtainium and unicorns??

For around $5 I received a very impressive module AND a camera to suit. Yummy!

And look at those specs!

Of course, unicorns may fly very fast, but first you have to catch one and communicate with it - not so easy!

The main issues for me revolved around having to:

1. learn a new programming language to talk to this thing (lua) as well as,

2. installing Windows (when I use Linux exclusively) and finally,

3. the majority of the support/software is Chinese based as well!

After much faffing about and grumbling I had to eventually concede defeat. I am going to check in from time to time to see if some geniuses have made this lovely piece of hardware accessible for dumbos like myself (e.g. via an Arduino IDE based library)

Until then - I'll enjoy looking at it.




Thursday, April 13, 2023

0000 0000 1100 0101

Mailbag #30

A testament to late night ordering is the arrival of not one, but two idiotic purchases - AC direct LEDs!

I'm very unlikely to want to fry myself with that nonsense, so they'll go straight to the bottom drawer.

In a few decades time one of my descendants will find them and shake their head at my hubris.

In the meantime you can shake your head at my hubris AND see some other useful stuff that arrived around the same time.

Enjoy the mailbag!



Friday, April 7, 2023

0000 0000 1100 0100

Unoffical safety car

Recently I was basking in the noise and fragrance of World Superbikes when I noticed some flashing lights. Atop the safety cars were red repeater lights and I started to wonder if that could be reproduced using a breadboard and a 555 timer.

It turns out that two 555 timers are required and that is exactly what is in a 556 IC.

I modelled the circuit using two 555 chips because of the limitations of the software, but built it using a 556 as seen below.



Apart from a little hiccup involving some missing links between trigger and threshold, the circuit works really well, exactly as simulated.

In fact, I attached it to an actual car for that final dash of realism to compare it to the original safety car footage from Phillip Island!


Friday, March 31, 2023

0000 0000 1100 0011

The Dirty Dozen - Part Three - curious HC-SR04 module

Out of the box this week comes an "intermediary" module - it hooks up to the HC-SR04 ultrasonic range finder module, displays the distance in cm, and can then output serial data via UART.

The blurb on the module claims that it is STM8S103 based, but the actual chip is a Nuvoton N76E003AT20, which is pretty obscure but the website gives the following:

N76E003 – a 1T-8051 based series MCU, offers 18 KB Flash ROM, configurable Data Flash and 1 KB SRAM. It supports wide operating voltage of 2.4V to 5.5V, temperature range of -40℃ to 105℃, and high noise immunity of 7KV ESD and 4KV EFT.


The chip needs a special programmer if you'd like to chat to it, but even if you could get to it (i.e. de-solder and find a suitable cradle), I'm really not sure how you would alter the code etc to be a bit friendlier - so that's not likely to happen.

As a result of this weirdness I did the obvious and looked at the serial output. It seems that every half second or so it outputted the following wacky string - "D: XXX\R\N". I'm assuming "D" is distance?

I had to cleave off the XXX (representing the actual distance) using the substring() function, and then convert the result to a number.

It worked, but boy is it clunky!

Here is the complete code which outputs to a coloured 10-segment LED module to visually aid distance indication.

// From https://www.programmingelectronics.com/serial-read/
// by Michael James, also
// many thanks to Nick Gammon for the basis of this code
// http://www.gammon.com.au/serial

const unsigned int MAX_MESSAGE_LENGTH = 12;
String convert;
int distance;
void setup() {
  Serial.begin(9600);
  DDRC = B00011111;
  DDRD = B11111000;
}

void loop() {

  //Check to see if anything is available in the serial receive buffer
  while (Serial.available() > 0)
  {
    //Create a place to hold the incoming message
    static char message[MAX_MESSAGE_LENGTH];
    static unsigned int message_pos = 0;

    //Read the next available byte in the serial receive buffer
    char inByte = Serial.read();

    //Message coming in (check not terminating character) and guard for over message size
    if ( inByte != '\n' && (message_pos < MAX_MESSAGE_LENGTH - 1) )
    {
      //Add the incoming byte to our message
      message[message_pos] = inByte;
      message_pos++;
    }
    //Full message received...
    else
    {
      //Print the message (or do other things)
      convert = (String)message;
      convert = convert.substring(2, 5);
      distance = convert.toInt();

      if (distance > 27) {
        PORTC = B00000001;
        PORTD = B00000000;
      }
      else if (distance > 24) {
        PORTC = B00000011;
        PORTD = B00000000;
      }
      else if (distance > 21) {
        PORTC = B00000111;
        PORTD = B00000000;
      }
      else if (distance > 18) {
        PORTC = B00001111;
        PORTD = B00000000;
      }
      else if (distance > 15) {
        PORTC = B00011111;
        PORTD = B00000000;
      }
      else if (distance > 12) {
        PORTC = B00011111;
        PORTD = B10000000;
      }
      else if (distance > 9) {
        PORTC = B00011111;
        PORTD = B11000000;
      }
      else if (distance > 6) {
        PORTC = B00011111;
        PORTD = B11100000;
      }
      else if (distance > 3) {
        PORTC = B00011111;
        PORTD = B11110000;
      }
      else if (distance > 0) {
        PORTC = B00011111;
        PORTD = B11111000;
      }

      //Reset for the next message
      message_pos = 0;
    }
  }
}

I really want to use this module combo on a robot car to do some auto-parking!

If you like the idea, leave a comment on here or in the comments section of the video below.

Enjoy the Dirty Dozen Part III.




 

Friday, March 24, 2023

0000 0000 1100 0010

555 Charge Pump Circuit (noisy PCB)

Recently I made up a 555 square wave generator using a kit that I dug out of the Dirty Dozen box. I thought I would take another at this PCB because I ran out of time to both troubleshoot the circuit and also to use it as I intended in a voltage doubler charge pump circuit.

The trouble shooting was made easy when a viewer suggested to check the power supply. Sure enough I was using a commercial direct buck/boost converter, which of course provided a pretty "bumpy" 12V.

Once I ran the source through an LM338 voltage regulator, and added a couple of smoothing capacitors, the 555 signal cleared up nicely.

Now with the signal sorted I whipped up a quick voltage doubler circuit according to one of the many versions available online, which worked a treat!

Here is the resultant video - enjoy!



Friday, March 17, 2023

0000 0000 1100 0001

The Dirty Dozen - Part Two - RPi Clone

This week I pulled out of the Dirty Dozen box a very cool RPi PICO clone.

To set myself a bit of a task I decided to program in MicroPython using Thonny, not the usual C via the Arduino IDE.

I had seen online some scuttlebutt about the ADC on these things being a little tricky, so I decided to test it out using an LDR which would then affect the integrated WS2812 LED to display light levels.

My Python skills were a little rusty, but after borrowing heavily from the internet, I was able to code the following.

import array, time
from machine import Pin
import rp2
 
# Configure the number of WS2812 LEDs, pins and brightness.
NUM_LEDS = 1
PIN_NUM = 23
brightness = 0.1

ldr = machine.ADC(27)
lightled = 0

BLACK = (0, 0, 0)
RED = (255, 0, 0)
YELLOW = (255, 150, 0)
GREEN = (0, 255, 0)
CYAN = (0, 255, 255)
BLUE = (0, 0, 255)
PURPLE = (180, 0, 255)
WHITE = (255, 255, 255)
COLORS = (WHITE, CYAN, YELLOW, GREEN, PURPLE, RED, BLUE, BLACK)

@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT, autopull=True, pull_thresh=24)
def ws2812():
    T1 = 2
    T2 = 5
    T3 = 3
    wrap_target()
    label("bitloop")
    out(x, 1)               .side(0)    [T3 - 1]
    jmp(not_x, "do_zero")   .side(1)    [T1 - 1]
    jmp("bitloop")          .side(1)    [T2 - 1]
    label("do_zero")
    nop()                   .side(0)    [T2 - 1]
    wrap()
 
# Create the StateMachine with the ws2812 program, outputting on Pin(16).
sm = rp2.StateMachine(0, ws2812, freq=8_000_000, sideset_base=Pin(PIN_NUM))
 
# Start the StateMachine, it will wait for data on its FIFO.
sm.active(1)
 
# Display a pattern on the LEDs via an array of LED RGB values.
ar = array.array("I", [0 for _ in range(NUM_LEDS)])
 
def pixels_show():
    dimmer_ar = array.array("I", [0 for _ in range(NUM_LEDS)])
    for i,c in enumerate(ar):
        r = int(((c >> 8) & 0xFF) * brightness)
        g = int(((c >> 16) & 0xFF) * brightness)
        b = int((c & 0xFF) * brightness)
        dimmer_ar[i] = (g<<16) + (r<<8) + b
    sm.put(dimmer_ar, 8)
    time.sleep_ms(10)
 
def pixels_set(i, color):
    ar[i] = (color[1]<<16) + (color[0]<<8) + color[2]
 
def pixels_fill(color):
    for i in range(len(ar)):
        pixels_set(i, color)
    
for color in COLORS:
    pixels_fill(color)
    pixels_show()
    time.sleep(1.5)
    
while True:
     lightled = ldr.read_u16()
     print(lightled)

     if lightled > 25000:
         pixels_fill(WHITE)
     elif lightled > 24000:
        pixels_fill(CYAN)
     elif lightled > 21000:
        pixels_fill(YELLOW)
     elif lightled > 18000:
        pixels_fill(GREEN)
     elif lightled > 15000:
        pixels_fill(PURPLE)
     elif lightled > 12000:
        pixels_fill(RED)
     elif lightled > 9000:
        pixels_fill(BLUE)
     elif lightled > 6000:
        pixels_fill(BLACK)

     pixels_show()
     time.sleep(0.2)

Loading up into the module was a breeze, and the second instalment of the Dirty Dozen was a success.