Thursday, June 2, 2022

0000 0000 1001 1000

LGT8F328P fakers

The clone of the AVR/MicroChip ATMega328 microcontroller IC by Logic Green is another sign that Chinese manufacturers are stepping up their game.

The LGT8F328P is a handy (and cheaper) alternative to it's ATMega328 antecedent and boasts a faster processing speed 32MHz vs 20MHz.

I have tried these processors before, but only somewhat unsuccessfully in some type of NRF24L01 FrankenNano module featured in a previous video and blog.


But cursed as I am to pursue non-standard non-useful tech, I found myself in reception of a couple of "legitimate" fakes - the famous forbidden green modules.


This prompted me to explore the FrankenNano again - and to save you all the trouble, they really are just too much trouble!




Saturday, May 28, 2022

0000 0000 1001 0111

Mailbag #14 - all about the projects

A month or so ago I became enarmoured with a couple of projects in particular - one was from Great Scott who featured a PCB/Solder reflow project from Chris at AfterEarthLTD.

A smart person might wait until these are available for sale, but I'm not that person so I ordered the PCB and the parts to make my own version (hooray for open source).

Another great project emerged from the brain of Big Clive who designed a PCB to safely trickle charge NiMH and NiCad batteries. Again I ordered the PCB and some parts (to be honest I didn't really need the "parts" - just some nice 120Ω resistors in the end).

This mailbag is where some of these items happily arrive, next - to the soldering iron!




Friday, May 20, 2022

0000 0000 1001 0110

LM3915 LED display driver

At least a couple of years ago I took delivery of LM3914, LM3915 and LM3916 LED display driver ICs.

The most common application for these devices is to drive an array of LEDs in response to an input (e.g. sound), to make a digital version of the analog VU-meter shown below.

The LM3914 can process an analog signal in a linear fashion, the LM3915 operates the same but in a logarithmic manner, and finally the LM3916 is logarithmic and has been specifically optimised for audio applications.

I found quite a few different circuits online which described the usage of this chip, and had couple of false starts as a result.

In particular, the microphone works w-a-y better with a simple amplifier between the microphone and the chip, and for that I used an LM358 OpAmp circuit as shown below.

The final result works so well it has rather unusually sat on my bench for a few days for fun, normally I dismantle such circuits pretty quickly. In fact is part of an intro for a future mailbag. Nice one!





Tuesday, May 10, 2022

0000 0000 1001 0101

Unlucky mailbag #13

This week I claw open some mail (literally) and try to figure out in a hilarious fashion what I was thinking at time of order!


 

Saturday, May 7, 2022

0000 0000 1001 0100

A box for all seasons

A little while ago on Twitter I saw a post from @sad_electronics about an online "box designer" for 3D printers.


I love to FreeCad as much as the next person, but this site intrigued me - could I really "whip up" a box in a few minutes and then print it out so that I could hold it in my hands a few hours later? My Precious!



Friday, April 29, 2022

0000 0000 1001 0011

Redesigning an old project - a hallway PWM light

A few years ago I made a few hallway lights which definitely favoured function over form. They were so UGLY and also had two power supplies, one for the lights (9V) and one for the microcontroller (3V - 2AA cells).


They worked and were surprisingly robust and useful! I have since improved my coding skills to include better sleeping for the ATTiny13, and my electronics skills have increased to the point where I am more confident running useful lights from a single power supply.

Also in the interim I designed a PCB for the project.



Next I would like to maybe move the LDR to the PIR unit as per this information, and also play around with the number and type of LEDs.

The code is quite simple - perhaps an ASM version would be even slimmer, but for now this seems fine.

// -----------------------------------------------------------------
// Description: A couple of parallel Leds connected to a transistor
// controlled by an Attiny13. The μC sleeps most of the time,   but is 
// interrupted by a PIR on PB2,   The μC then checks the light 
// levels.  If it's light then it will sleep again,   but if it's dark
// it will light the leds slowly,   hold for awhile and and then fade
// out.
// 
// Author: OneCircuit            Date: Thu 31 Mar 2022 18:28:44 AEDT
// -----------------------------------------------------------------
// 
// ATMEL 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/pgmspace.h>     // for reading the progmem values
#include <avr/sleep.h>        // the sleep routines

#define LEDs PB0              // pwm pin
#define InterruptPin PB2      // interrupt pin

#define photoresistor A2      // A2 analog in

// The leds will fade exponentially to compensate for human perception,  
// which is not linear. You can calculate as a curve,   but float
// values will blow the little Attiny13 out of the water,   so a lookup
// table in progmem makes more sense for saving memory. 

const uint8_t PROGMEM fadevalues[] = {

  0,    0,    0,    0,    0,    0,    0,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    2,
  2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    3,
  3,    3,    3,    3,    3,    3,    3,    3,    3,    3,    3,    4,    4,    4,    4,    4,
  4,    4,    4,    4,    4,    5,    5,    5,    5,    5,    5,    5,    5,    6,    6,    6,
  6,    6,    6,    7,    7,    7,    7,    7,    7,    8,    8,    8,    8,    8,    8,    9,
  9,    9,    9,    10,   10,   10,   10,   10,   11,   11,   11,   11,   12,   12,   12,   13,
  13,   13,   13,   14,   14,   14,   15,   15,   15,   16,   16,   16,   17,   17,   18,   18,
  18,   19,   19,   20,   20,   20,   21,   21,   22,   22,   23,   23,   24,   24,   25,   25,
  26,   27,   27,   28,   28,   29,   30,   30,   31,   32,   32,   33,   34,   35,   35,   36,
  37,   38,   38,   39,   40,   41,   42,   43,   44,   45,   46,   47,   48,   49,   50,   51,
  52,   53,   54,   55,   57,   58,   59,   60,   62,   63,   64,   66,   67,   69,   70,   72,
  73,   75,   76,   78,   80,   81,   83,   85,   87,   88,   90,   92,   94,   96,   98,   100,
  103,  105,  107,  109,  112,  114,  117,  119,  122,  124,  127,  130,  132,  135,  138,  141,
  144,  147,  150,  153,  157,  160,  164,  167,  171,  174,  178,  182,  186,  190,  194,  198,
  202,  206,  211,  215,  220,  224,  229,  234,  239,  244,  249,  255,  255,  255,  255,  255 };

void powerDown(void)
{
    GIMSK |= (1<<PCIE);                   // activate Pin change interrupts
    PCMSK |= (1<<InterruptPin);           // sets the Pin change interrupt mask
    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
    BODCR |= (1<<BODS)|(1<<BODSE);        // turn off brownout detection
    BODCR |= (1<<BODS);
    BODCR &= ~(1<<BODSE);
    
    sleep_enable();                       // enable sleep mode
    sleep_mode();                         // system sleeps here
    
    sleep_disable();                      // ISR routine returns here so wake up        
    GIMSK &= ~(1<<PCIE);                  // deactivate Pin change interrupts
    ADCSRA |= (1 << ADEN);                // turn on ADC
    ACSR = (0<<ACD);                      // turn on Analog comparator.
    delay(50);                            // settle time

    // read the input pin, local variable saves memory
    uint16_t val = analogRead(photoresistor);    

    if(val < 250) {
    pinMode(5,OUTPUT);
    slowfade(true);               // fade in
    delay(30000);                 // hold that thought
    slowfade(false);              // fade out
    pinMode(5,INPUT_PULLUP);

    }

}

void slowfade(boolean fadein){

if (fadein) {
  for (uint8_t lighting = 0; lighting < 255; lighting++){    
    analogWrite(LEDs, pgm_read_byte(&fadevalues[lighting]));  // read from the lookup table
    delay(5);                                                // increase for a slower fade
  }
}
else {
  for (uint8_t lighting = 255; lighting > 0; lighting--){     // count backwards
    analogWrite(LEDs, pgm_read_byte(&fadevalues[lighting]));  // from the lookup table
    delay(50);                                                // increase for a slower fade 
}
}
}

ISR(PCINT0_vect)
{
  // wake up little one...
}

void setup ()
{
  // all inputs and pullups to save power
  pinMode(1,INPUT_PULLUP);
  pinMode(2,INPUT_PULLUP);
  pinMode(3,INPUT_PULLUP);
  pinMode(5,INPUT_PULLUP);
  pinMode(6,INPUT_PULLUP);
  pinMode(7,INPUT_PULLUP);
}  // end of setup

void loop () {
  powerDown(); // call the function that sleeps
}

In the meantime - these updated units are working fine (and so much prettier!)




Sunday, April 24, 2022

0000 0000 1001 0010

Mailbag #12 - unearthing treasure

Lost in the move from an HDD to an SSD, several package openings have come to light recently. They are a little venerable, but I though it might be useful to cobble a few together and make a franken-mailbag. Enjoy!