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!
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/serialconstunsignedint 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 bufferwhile (Serial.available() > 0)
{
//Create a place to hold the incoming messagestaticchar message[MAX_MESSAGE_LENGTH];
staticunsignedint message_pos = 0;
//Read the next available byte in the serial receive bufferchar inByte = Serial.read();
//Message coming in (check not terminating character) and guard for over message sizeif ( 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;
}
elseif (distance > 24) {
PORTC = B00000011;
PORTD = B00000000;
}
elseif (distance > 21) {
PORTC = B00000111;
PORTD = B00000000;
}
elseif (distance > 18) {
PORTC = B00001111;
PORTD = B00000000;
}
elseif (distance > 15) {
PORTC = B00011111;
PORTD = B00000000;
}
elseif (distance > 12) {
PORTC = B00011111;
PORTD = B10000000;
}
elseif (distance > 9) {
PORTC = B00011111;
PORTD = B11000000;
}
elseif (distance > 6) {
PORTC = B00011111;
PORTD = B11100000;
}
elseif (distance > 3) {
PORTC = B00011111;
PORTD = B11110000;
}
elseif (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.
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.
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", [0for _ in range(NUM_LEDS)])
def pixels_show():
dimmer_ar = array.array("I", [0for _ 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)
whileTrue:
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.
A few months ago in a late night frenzy I bought 12 items from the same supplier. Sick of opening parcels and promising on camera to do something with the package inside, I've made a commitment with this series to use the item straight away.
This week the random selection was a curious 555 kit which was so familiar to me as I had made a very similar project a couple of years ago.
Here it is in a build that took a little longer than expected!
I unashamedly love my Orange Pi-hole. Adverts are dropped, speed is increased and I can see and monitor the activity on the network, PLUS it has a really cool interface!
In a recent mailbag video when another Orange Pi arrived I asked via YT if anyone would be interested in how I maintain and update the device. YT spoke back!
In response to that request I have now made a video of what I do for regular maintenance. It's pretty simple and goes something like this:
1. ssh into the device using "ssh root@192.169.X.X" where XX is the local address
2. apt update
3. apt upgrade
4. pihole -up
That's it! There are quite a few other things that you can do from the console while we're here:
Usage: pihole [options]
Example: 'pihole -w -h'
Add '-h' after specific commands for more information on usage
Whitelist/Blacklist Options:
-w, whitelist Whitelist domain(s)
-b, blacklist Blacklist domain(s)
-wild, wildcard Blacklist domain(s), and all its subdomains
Add '-h'for more info on whitelist/blacklist usage
Debugging Options:
-d, debug Start a debugging session
Add '-a' to enable automated debugging
-f, flush Flush the Pi-hole log
-r, reconfigure Reconfigure or Repair Pi-hole subsystems
-t, tail View the live output of the Pi-hole log
Options:
-a, admin Admin Console options
Add '-h'for more info on admin console usage
-c, chronometer Calculates stats and displays to an LCD
Add '-h'for more info on chronometer usage
-g, updateGravity Update the list of ad-serving domains
-h, --help, help Show this help dialog
-l, logging Specify whether the Pi-hole log should be used
Add '-h'for more info on logging usage
-q, query Query the adlists for a specified domain
Add '-h'for more info on query usage
-up, updatePihole Update Pi-hole subsystems
-v, version Show installed versions of Pi-hole, Admin Console & FTL
Add '-h'for more info on version usage
uninstall Uninstall Pi-hole from your system
status Display the running status of Pi-hole subsystems
enable Enable Pi-hole subsystems
disable Disable Pi-hole subsystems
Add '-h'for more info on disable usage
restartdns Restart Pi-hole subsystems
checkout Switch Pi-hole subsystems to a different Github branch
Add '-h'for more info on checkout usage
-a Usage
Usage: pihole -a [options]
Example: pihole -a -p password
Set options for the Admin Console
Options:
-p, password Set Admin Console password
-c, celsius Set Celsius as preferred temperature unit
-f, fahrenheit Set Fahrenheit as preferred temperature unit
-k, kelvin Set Kelvin as preferred temperature unit
-r, hostrecord Add a name to the DNS associated to an IPv4/IPv6 address
-e, email Set an administrative contact address for the Block Page
-h, --help Show this help dialog
-i, interface Specify dnsmasq's interface listening behavior Add '-h'for more info on interface usage
To be honest however I only use the graphical interface on the system via a browser. The system works great - highly recommended!
To find out more about this project (and donate if you use it) click on this link.