Friday, January 26, 2024

0000 0000 1101 1111

Mailbag #37 from "Downtown Tasmania"

A really eclectic mix of weird and wonderful in these bags - including some parts that I completely mislabel, and some other parts that defy description.

Enjoy the madness!



Thursday, January 18, 2024

0000 0000 1101 1110

Quinque Lumina

I'm still fiddling with the code (current version below) and the layout of the famous PFS154 solar powered candle.


/*
  Candle with Three PWM

  Pseudo-random flickering to simulate a candle. Output is
  via 3xPWM channels, variables can be changed to
  alter the simulation

  Tue 16 Jan 2024 13:50:35 AEDT

*/

#include <stdint.h>
#include <stdlib.h>
#include "../device.h"
#include "../easy-pdk/calibrate.h"
#include "../auto_sysclock.h"
#include "../delay.h"
#include <stdbool.h>

#define LED4_BIT 4
#define LED0_BIT 0
#define LED3_BIT 3

uint16_t myrand = 2901;  // happy birthday

uint8_t slowcounter = 0;
uint8_t medcounter = 0;
uint8_t fastcounter = 0;
uint8_t slowstart = 0;
uint8_t slowend = 0;
uint8_t medstart = 0;
uint8_t medend = 0;
uint8_t faststart = 0;
uint8_t fastend = 0;
uint8_t faster = 0;

uint8_t waveslow[] = {15, 25, 60, 100};
uint8_t wavemed[] = {10, 25, 110, 140};
uint8_t wavefast[] = {20, 25, 100, 120};

bool fastup = true;
bool slowup = true;
bool medup = true;

void mydelay(uint8_t counter) {

  for (uint8_t thiscount = 0; thiscount <= counter; thiscount++) {
    _delay_us(1);
  }
}

uint16_t gimmerand(uint16_t small, uint16_t big) {
  myrand ^= (myrand << 13);
  myrand ^= (myrand >> 9);
  myrand ^= (myrand << 7);
  if (abs(myrand) % 13 == 0) {
    myrand = myrand - 23;
  }
  if (abs(myrand) % 17 == 0) {
    myrand = myrand + 11;
  }
  return abs(myrand) % 23 * (big - small) / 23 + small;
}

void getnewslow() {
  slowstart = gimmerand(waveslow[0], waveslow[1]);
  slowend = gimmerand(waveslow[2], waveslow[3]);
}

void getnewmed() {
  medstart = gimmerand(wavemed[0], wavemed[1]);
  medend = gimmerand(wavemed[2], wavemed[3]);
}

void getnewfast() {
  faststart = gimmerand(wavefast[0], wavefast[1]);
  fastend = gimmerand(wavefast[2], wavefast[3]);
  faster = gimmerand(2, 6);
}

// Main program
void main() {

  PAC |= (1 << LED4_BIT) | (1 << LED0_BIT) | (1 << LED3_BIT);

  // see datasheet
  PWMG1DTL = 0x00;
  PWMG1DTH = 0x00;
  PWMG1CUBL = 0xff;
  PWMG1CUBH = 0xff;
  PWMG1C = 0b10100111;
  PWMG1S = 0b00000000;

  PWMG0DTL = 0x00;
  PWMG0DTH = 0x00;
  PWMG0CUBL = 0xff;
  PWMG0CUBH = 0xff;
  PWMG0C = 0b10100111;
  PWMG0S = 0b00000000;

  PWMG2DTL = 0x00;
  PWMG2DTH = 0x00;
  PWMG2CUBL = 0xff;
  PWMG2CUBH = 0xff;
  PWMG2C = 0b10100111;
  PWMG2S = 0b00000000;

  getnewfast();
  getnewslow();
  getnewmed();
  slowcounter = slowstart;
  fastcounter = faststart;
  medcounter = medstart;

  // Main processing loop
  while (1) {

    // ramp up slow
    if (slowup) {
      slowcounter++;
      if (slowcounter > slowend) { // ramp finished so switch boolean
        slowup = !slowup;
      }
    }
    else {
      // ramp down slow
      slowcounter--;
      if (slowcounter < slowstart) { // ramp finished so switch boolean
        slowup = !slowup;
        getnewslow();
      }
    }

    // ramp up med
    if (medup) {
      medcounter++;
      if (medcounter > medend) { // ramp finished so switch boolean
        medup = !medup;
      }
    }
    else {
      // ramp down med
      medcounter--;
      if (medcounter < medstart) { // ramp finished so switch boolean
        medup = !medup;
        getnewmed();
      }
    }

    // ramp up fast
    if (fastup) {
      fastcounter = fastcounter + faster;
      if (fastcounter > fastend) { // ramp finished so switch boolean
        fastup = !fastup;
      }
    }
    else {
      // ramp down fast
      fastcounter = fastcounter - faster;
      if (fastcounter < faststart) { // ramp finished so switch boolean
        fastup = !fastup;
        getnewfast();
      }
    }
    // delay + a re-purposed random for ramp speeds
    mydelay(25 + faster);

    PWMG2DTL = slowcounter & 255;
    PWMG2DTH = slowcounter;
    PWMG0DTL = fastcounter & 255;
    PWMG0DTH = fastcounter;
    PWMG1DTL = medcounter & 255;
    PWMG1DTH = medcounter;

  }
}

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

  CLKMD = CLKMD_ILRC | CLKMD_ENABLE_ILRC | CLKMD_ENABLE_IHRC;
  CLKMD = CLKMD_ILRC | CLKMD_ENABLE_ILRC;
  PDK_SET_SYSCLOCK(SYSCLOCK_ILRC);
  EASY_PDK_CALIBRATE_ILRC(47000,4000);

  return 0;
}

Check out 5 new "candles" straight off the production line in the following video:



Friday, January 12, 2024

0000 0000 1101 1101

Hot Software or Hardware? Bullseye!

I upgraded my NAS Media Centre from an Orange Pi PC Plus to an Orange Pi 3 LTS, both running OpenMediaVault (OMV).

Apart from the usual configuration SNAFUs and other delights in such a move, I was a tad concerned about the reported CPU temperature on the new machine.

Logging into the new Orange Pi 3 LTS and using HTOP I consistently saw over 50 degrees Celsius - about 20 degrees higher than the Orange Pi PC Plus running Orange Pi's own Armbian image.

It's inevitable I surmise that with higher performance comes higher temperatures, but a little online chatter on the subject of software differences sent me on a typical OneCircuit rabbit hole expedition where I compared six(!) OS options based on temperature profile.

All images were homemade roll-yer-own Armbian based along the following lines:

Orange Pi PC Plus: Ubuntu Jammy, Debian Bullseye and Debian Bookworm

Orange Pi 3 LTS: Ubuntu Jammy, Debian Bullseye and Debian Bookworm

All images also were CLI only (no desktop) and I used the same micro SD card and ambient temperature for all tests - no fans employed but the chips did have heat sinks onboard.

If you want me to do a deeper dive on building your own Armbian images, or configuring OMV please leave a comment on YouTube (video link below).

The results of all this amateur science? Surprising!



Saturday, January 6, 2024

0000 0000 1101 1100

ESP32 and Pro Minis in for surgery

I recommended to peeps at work that they buy a bulk order (10pcs) of a cheap ESP32 module that the Science Dept can use for projects (I'm a high school teacher as well as a technology junky!)

Instant success as they applied one to a watering project - no IoT as yet but a start in the right direction.

Well I was less than impressed that two of the 10 did not work - I'd never had that trouble before with AliExpress orders so I felt duty bound to take the ailing items home for a little amateur surgery.

At the same time in the process of...er...experimentation with Arduino Pro Mini units trying to squeeze more power out of them for my KimUno project (blog and video) I had fried two of the unlucky blighters. More amateur surgery required?

You be the judge!