Saturday, September 26, 2020

0000 0000 0100 0010

An ATTiny85 function generator

I do a lot of teaching of "Electro-Technology", and nothing pleases me more than finding a treasure chest of potential projects to excite and educate the minds of the next generation. Case in point? David Johnson-Davies wonderful "Technoblogy" site. My students and I have built quite a few of these circuits and they continue to be popular.

The projects featured on David's site are wonderful in that they are carefully explained, have all the diagrams you would want, contain code if necessary and the resulting projects are both useful and work as designed. Actually, he's kind of my hero (along with Ćukasz Podkalicki and his similarly inspiring ATTiny13 blog)!

About a year or so ago I spied the ATTiny85 function generator on David's site.

One day when I'm a grown up I might buy a commercial function generator, but in the meantime this little guy looked amazing, and David made the PCB files available on github for those who wish to make their own. Yes please!

So I ordered a few and after they arrived I soldered one up and OMG it worked the first try, and it was wonderful. Here is mine plugged in and with power.



And of course below is the video of the device being built and then actually working (er, after a little altercation with a couple of recalcitrant OLED displays).





Saturday, September 19, 2020

0000 0000 0100 0001

"New improved" solar panel for Joule Thief lights

I don't just use the Joule Thief circuits for running ATTiny13s as fake candles, as outlined in a previous blog post, but also they come in handy for providing "normal" light to illuminate the house at night.

In our house we don't tend to turn lights on at night as we move around - these little solar fellas sit on the floor and provide enough light to avoid tripping over giant dark puppies that habitually lie about the place in a haphazard manner.

We've been using the lights for more than a year now and they work really well, however I did spy some up-spec solar panels that looked a treat (a bit smaller and tidier) and as well they promised better performance via a higher current output at the same voltage (a promised 160mA vs 130mA at 2V).

Testing the panels side by side

So after flicking on both the soldering iron and hot-glue gun, I was up for tinkering away with the next generation of solar lights.

Building the "new" version

Works a treat!






 

Saturday, September 12, 2020

0000 0000 0100 0000

ATTiny13 looks after big brother ATTiny85

For a couple of years now I've been thinking about watchdogs - circuits or microcontrollers that watch/report on the circuit itself. For instance, some time ago I had an ESP8266 in my hothouse reporting temperature, humidity and atmospheric pressure every few minutes.

When the battery ran low, I lost data. So I have been looking at the possibility of enlisting an ATTiny13 (of course) to monitor the voltage in a circuit and then act at some minimum voltage threshold to, for instance, preserve data.

Coupled with that, I have been looking into EEProm storage on the ATTinys - so it seems that there may be an opportunity to combine the two as a "proof of concept". An ATTiny13 monitoring the overall voltage of the circuit, and an ATTiny85 storing data and perhaps shutting down when signalled by the "watchdog".


The code for the ATTiny85 is below. It just counts, and then when interrupted by the ATTiny13 it will display a "low battery" message, write the data to the EEProm and then shut down until the voltage/microcontroller is reset.

// ATTiny85 counts and if interrupted saves the count and then sleeps
// OneCircuit Thursday 10 September  19:18:08 AEST 2020

#include <EEPROM.h>
#include <avr/sleep.h>
#include <TM1637Display.h>

// pins to talk to the TM1637 display
#define CLK 2
#define DIO 1

int thisnumber = 0;             // counter
int address = 0;                // eeprom address
volatile bool LValarm = false;  // has the voltage dropped? Set "no"

// to make the word Low Battery in TM1637 speak
const uint8_t Lo_b[] = {
  SEG_F | SEG_E | SEG_D,                     // L
  SEG_G | SEG_E | SEG_D | SEG_C,             // o
  SEG_D,                                     // _
  SEG_F | SEG_G | SEG_E | SEG_C | SEG_D      // b
};


TM1637Display display(CLK, DIO);

void writetheeeprom() {
  EEPROM.put(address, thisnumber);
}

// Interrupt arrived from the ATTiny13!
ISR(PCINT0_vect) {
  LValarm = true;
}

void setup() {
  display.setBrightness(0x02);
  EEPROM.get(address, thisnumber);
  pinMode(PB3, INPUT);
  ADCSRA &= ~(1 << ADEN); // disable ADC (before power-off)
  GIMSK = 0b00100000;     // turns on pin change interrupts
  PCMSK = 0b00001000;     // turn on interrupts on pins PB3
  sei();                  // enables interrupts
}

void loop() {

  // routine while voltage is OK
  while (!LValarm) {
    thisnumber++;
    if (thisnumber > 9999) {
      thisnumber = 0;
    }
    display.showNumberDec(thisnumber, false);
    delay(75);
  }

  // shutdown routine
  writetheeeprom();
  display.setSegments(Lo_b);
  delay(10000);
  display.clear();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_cpu(); // wake upon reset
}


The code for the ATTiny13 is below. It monitors the voltage, giving a visual clue (Green LED) if the voltage is above the threshold, and another (Red LED) if the voltage falls below.

// ATTiny13 monitors PB3 and sends a pulse out if voltage drops
// OneCircuit Thursday 10 September  19:18:08 AEST 2020

int vcc = 0;
bool trigger85 = false;
int volt_threshold = 850;
bool debug = false;

void setup() {

  pinMode(PB1, OUTPUT);
  pinMode(PB2, OUTPUT);
  pinMode(PB4, INPUT_PULLUP);
  pinMode(PB3, INPUT_PULLUP);
  analogReference(INTERNAL);   // use internal 1.1V as reference
  delay(1000);   // settle time
}

void loop() {

  vcc = analogRead(PB3);

  // if voltage is OK and we haven't triggered, display green
  while (vcc > volt_threshold && !trigger85) {
    vcc = analogRead(PB3);
    digitalWrite(PB2, HIGH);
    delay(50);
    digitalWrite(PB2, LOW);
    delay(2000);
  }

  // send the pulse
  if (!trigger85) {
    pinMode(PB4, OUTPUT);
    digitalWrite(PB4, HIGH);
    delay(100);
    digitalWrite(PB4, LOW);
    delay(10);
    trigger85 = true;
  }
  // red lights
  digitalWrite(PB1, HIGH);
  delay(50);
  digitalWrite(PB1, LOW);
  delay(2000);
  
}

It works great and you can see the result in the video below.






Saturday, September 5, 2020

0000 0000 0011 1111

LM358 triangle and sine wave generator

Not content with a simple LM358 square wave generator as seen on the last blog, I look this week at converting the square wave to other wave forms using the mathematical functionality of OpAmps. Casting about in the shallow end of the internet pool, I happened upon this variation of the previous circuit.

After lots of playing about on iCircuit and some deeper internet trawling, I was able to make the circuit work on a simulator as follows.

It was a little concerning that the signal degrades in voltage over the three opAmps, such that the final voltage fluctuation is only around 2V from a 9V supply. I tried to rope in a transistor to amplify (with no real success) but I'll keep trying to amplify the signal - probably with the "free" side of the second opAmp maybe something like the following:

The final (simplified) design, using only 10k resistors and 10uF capacitors, looks a treat "In Real Life" and it functions (pun intended) as designed!