Saturday, February 27, 2021

0000 0000 0101 0110

Plastic Fantastic

Years ago I saw a Sesame Street episode where a glass of milk is knocked over and a child makes up all sorts of stories about the accident rather than admit guilt (including the famous "Man in a Gorilla Suit" excuse).

In a similar vein I was filming close-ups with a USB digital camera when <**SNAP**> and the semi-circular plastic component that holds the camera body ended up broken.

Rather than admit guilt, I set about designing and printing a replacement. The process extended my FreeCad knowledge and resulted in a new component that fitted the holder exactly and behaved as designed.

Along the way I learned some new skills and resurrected my digital camera holder.

Good result!









 

Saturday, February 20, 2021

0000 0000 0101 0101

Endless random LEDs

I have spent many hours trying to figure out how I could use a TO-92 QX5252 to give continuous reliable current all day from a solar panel, when in it's natural state it is configured to shut off at night time.

In a previous blog and YouTube video I triumphantly showed how it could be done by using two such ICs.

Well, the triumph was short-lived as LCSC sent me some SOT23-5 form factor ICs with an extra pin! What could it mean? The datasheet referred to it as LS (light sensor?) but declined to give any useful information about it's function.

So I mounted one of the tiny guys on a SOP8 to DIP adapter and then using a mock up of the circuit on a breadboard I found to my great delight that if the LS was held to ground, the QX5252 was designed to output constantly to pin3. 

Also I was simultaneously devastated for all the work trying to make the TO-92 package do the same!



Now a little bit of 4-LED random code for the ATTiny13 as follows:

// -----------------------------------------------------------------
// Description: A lightshow built on four "random" LEDs which flick
// on or off for a random amount of time depending on which state
// is selected.
//
// Author: OneCircuit                              Date: 28/01/2021
// -----------------------------------------------------------------
//
// MicroChip ATTINY13 μC
//
//                                   +-\/-+
//  RESET--ACD0--5/A0--PCINT5--PB5  1|    |8  VCC
//   CLKI--ACD3--3/A3--PCINT3--PB3  2|    |7  PB2--PCINT2--2/A1--SCK--ADC1
//         ACD2--4/A2--PCINT4--PB4  3|    |6  PB1--PCINT1---1---MISO--OCOB--INT0*
//                             GND  4|    |5  PB0--PCINT0---0---MOSI--OCOA*
//                                   +----+
//  * indicates PWM port
//

#include <avr/sleep.h>        // the sleep routines

byte getleds = 0b00000000;    // initial all leds off
byte sleeptime = 0;           // initial timer = 0
uint16_t myrand = 2901;       // initial seed -> happy birthday

void setup() {
  DDRB = 0b00001111;          // only four outputs
  PORTB = 0b11110000;         // the rest input pullup
  myrand = myrand+analogRead(PB4);   // reset the seed
} ISR(WDT_vect) { } // generate a "random" number between small and big uint16_t gimmerand(uint16_t small, uint16_t big) { myrand ^= (myrand << 13); myrand ^= (myrand >> 9); myrand ^= (myrand << 7); return abs(myrand) % 23 * (big - small) / 23 + small; } void powerDown(void) { MCUCR = 0b00110000; // see datasheet WDTCR = 0b01000010; // 64ms ADCSRA &= ~(1 << ADEN); // turn off ADC ACSR |= (1 << ACD); // turn off Analog comparator. sei(); // enable global interrupts set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep deeply little one sleep_enable(); // enable sleep mode cli(); // Disable BOD steps BODCR = (1 << BODSE) | (1 << BODS); BODCR = (1 << BODS); sei(); sleep_cpu(); sleep_disable(); // ISR routine returns here so wake up ADCSRA |= (1 << ADEN); // turn on ADC ACSR = (0 << ACD); // turn on Analog comparator. delay(10); // settle time } void loop() { getleds = gimmerand(0, 16); // returns 0..15
  sleeptime = gimmerand(1, 25);
  PORTB = getleds;
  for (int howmanysleeps = 0; howmanysleeps < sleeptime; howmanysleeps++) {
    powerDown();
  }
}

In my mind I wanted to make a neat little package to put the whole shebang into, so I whipped up a 3D printed enclosure, soldered up the circuit and popped the result on the windowsill to flicker away randomly, perhaps forever?

P.S. Update - 4 weeks and still going strong...




Saturday, February 13, 2021

0000 0000 0101 0100

CD4023 triple input NAND gate

Mostly if you want to set up conditions for something to happen electronically then it's pretty normal these days to reach for a cheap microcontroller and with a few lines of code the job is done. For instance, imagine that you need a light in a car to be "ON" (lit) if one or more doors are open. It is quite a simple program, no dramas.

BUT, imagine there is a worldwide shortage of microcontrollers and all that you have are a few logic chips in the bottom of a component bin. In particular, you see a CD4023 triple input NAND gate.

If we look at the logic table and connect up the chip correctly, can we not use this to set up the required conditions, just like the old days?



Of course! So in this circuit I use an 8-way dip switch to simulate a car door opening or closing (6V coming in through a 1k resistor indicating closed or "1").

The CD4023 is configured such that 5 doors of our imaginary hatchback must be closed before the "alarm" output LED is doused. Well, you can see how well it works in the following video.



Saturday, February 6, 2021

0000 0000 0101 0011

PFS154 "unleashed"

Now that I have a working Padauk programmer, I am keen to explore the capabilities of these chips. The interesting quirk straight up is that these chips sink current - that is the opposite to what I have experienced with AVR chips.

My first thought was of how to make use of this "feature" as an output as per my experience. With not much sophistication I whipped up a "NOT" gate using a SS8050 transistor as we've seen on this blog before.

So then I fed the "reversed" signal to the ULN2803 (of yet another previous blog), and modified the code that comes with the freepdk programmer project as below.

/*
  BlinkLED

  Turns an LED on for one second, then off for one second, repeatedly.
  Uses a timing loop for delays.
*/

#include <pdk/device.h>
#include "auto_sysclock.h"
#include "delay.h"

// LED is placed on the PA3 pin (Port A, Bit 3) with a current sink configuration
#define LED 3

// LED is active low (current sink), so define helpers for better readability below
#define turnLedOn()   PA = 0b00000000   // original:  PA &= ~(1 << LED_BIT)
#define turnLedOff()  PA = 0b00001000   //            PA |= (1 << LED_BIT)

// Main program
void main() {

  // Initialize hardware
  PAC = 0b00001000;          // original: PAC |= (1 << LED_BIT);
  turnLedOff();

  // Main processing loop
  while (1) {
    turnLedOn();
    _delay_ms(200);
    turnLedOff();
    _delay_ms(1200);
  }
}

// Startup code - Setup/calibrate system clock
unsigned char _sdcc_external_startup(void) {

  AUTO_INIT_SYSCLOCK();
  AUTO_CALIBRATE_SYSCLOCK(TARGET_VDD_MV);

  return 0;   // Return 0 to inform SDCC to continue with normal initialization.
}

Finally, as the ULN2803 also sinks (large) current, I pressed a 3W LED into action and had some major blinky action.

I know it does not seem like much, but there was real joy in finally making a "project" using the Padauk at the heart. I've got my sights set on PWM next - maybe controlling a motor (the ULN2803 also reputedly does excellent work in this regard).