An offcut from the Fraktalismus pattern factory

This animation, which I created by accident while trying to do something else, struck me as eye catching.

This is the complete C code used to generate video frames as individual PNM image files:

//
// offcut.c
// Written by Ted Burke, 1-2-2018
// See http://batchloaf.com
//
// To build:
//     gcc -O3 -Wall -o offcut offcut.c -lm
//
// To run:
//     ./offcut 0 1 400
//
// To combine individual frames into a movie:
//     
//     ffmpeg -framerate 8 -f image2 -s 1920x1080 -i %03d.pnm -framerate 8 -s 1920x1080 -i %03d.pnm -filter_complex "[0:v:0][1:v:0]concat=n=2:v=1[outv];[outv]scale=1920x1080[outv]" -c:v libx264 -preset slow -crf 17 -pix_fmt yuv420p -c:a copy -map [outv] -r 8 offcut.mkv
//

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>

#define W 3840
#define H 2160

unsigned char p[H][W][3] = {0};

int main(int argc, char **argv)
{
    int n, N=25, x, y, v, t, t_start, t_step, T;
    complex double z, c;
    double zlim = 10.0;
    char filename[1024];
    FILE *f;
    
    t_start = atoi(argv[1]);
    t_step = atoi(argv[2]);
    T = atoi(argv[3]);
    fprintf(stderr, "t_start:%d t_step:%d T:%d\n", t_start, t_step, T);
    
    for (t=t_start ; t<T ; t+=t_step)
    {
        // Vary parameter
        c = -0.825 -0.1*I - 0.2*cexp(I*t*2.0*M_PI/T);
        
        // Generate pixels
        for (y=0 ; y<H ; ++y) for (x=0 ; x<W ; ++x)
        {
            z = 0.002 * (I*(x-W/2.0) + (y-H/2.0));
            
            // This iterating function makes a good texture - it's unusual!
            for (n=0 ; n<N && cabs(z)<zlim ; ++n) z = 1 / (cpow(z,z+c) + c);
            
            // Colour mapping from angle of final z value to shade of blue
            v = 128.0 + 127.0 * carg(z)/M_PI;
            p[y][x][0] = v>127 ? 2*(v-127) : 0;
            p[y][x][1] = v>127 ? 2*(v-127) : 0;
            p[y][x][2] = v>127 ? 255 : 2*v;
        }
        
        // Write current frame to a PNM image file
        sprintf(filename, "%03d.pnm", t);
        fprintf(stderr, "Writing file %s...", filename);
        f = fopen(filename, "w");
        fprintf(f, "P6\n%d %d\n255\n", W, H);
        fwrite(p, 3, W*H, f);
        fclose(f);
        fprintf(stderr, "done\n");
    }
    
    return 0;
}

I decided to render the frames at double resolution (3840 x 2160 px) and then scale back down to 1080p resolution during the video conversion. This was the ffmpeg command I used to combine PNM images into a single video at 8 frames per second, with the full sequence repeated twice:

ffmpeg -framerate 8 -f image2 -s 1920x1080 -i %03d.pnm -framerate 8 -s 1920x1080 -i %03d.pnm -filter_complex "[0:v:0][1:v:0]concat=n=2:v=1[outv];[outv]scale=1920x1080[outv]" -c:v libx264 -preset slow -crf 17 -pix_fmt yuv420p -c:a copy -map [outv] -r 8 mugz.mkv
Advertisements
Posted in Uncategorized | Leave a comment

Cafe Terrace at Starry Night

Image | Posted on by | 1 Comment

€2 Robots in DIT

In this video, I chat with Kevin Chubb about his final-year project on ultra low-cost swarm robotics, here in DIT’s School of Electrical and Electronic Engineering. Kevin’s designing robots that can be built by hand from less than €2 worth of off-the-shelf parts. He doesn’t quite have a swarm yet, but in the video we get to see one of his tiny robots scuttling to and fro.

I for one welcome our competitively priced new robotic overlords!

Posted in Uncategorized | Tagged , , , , , , , , , , , , | 2 Comments

A brief introduction to binary numbers…

Posted in Uncategorized | Tagged , , , , | Leave a comment

Can the PIC12F675 drive motors directly from its GPIO pins?

As I mentioned in my previous post, my project student Kevin Chubb is developing tiny ultra low cost robots using a PIC12F microcontroller. One of the things that’s great about PICs is that they can source and sink relatively high current through their digital i/o pins. Kevin and I have been hoping that it might be possible to build a robot that powers its actuators directly from the microcontroller pins, so that was a big factor in choosing the PIC12F. Anyway, yesterday I received a package of tiny “coreless” motors in the post from AliExpress, so I’ve just carried out an experiment to see if they can be powered directly from the GPIO pins of a PIC12F.

I received two types of motors in yesterday’s delivery, but the ones I’m using in this experiment are these ones:

To begin with, I measured the current drawn by one of the motors when it was running unloaded at 3V, which turned out to be approximately 31 mA. Although that’s slightly higher than the rated pin current on the PIC12F (25 mA), I decided it was worth taking a chance and I set up an experiment with two of the motors connected directly to a PIC12F675. Here’s the video:

The complete code is used is shown below:

//
// PIC12F675 example: motors on GP4 and GP5
// Written by Ted Burke - 20-4-2017
//
// To compile:
//
//    xc8 --chip=12F675 main.c
//
 
#include <xc.h>
 
#pragma config FOSC=INTRCIO,WDTE=OFF,MCLRE=OFF,BOREN=OFF
 
void main(void)
{
    TRISIO = 0b11001111; // Make pins GP4 and GP5 outputs
    ANSEL  = 0b00000000; // Disable all analog inputs
     
    while(1)
    {
        GP4 = 1;         // Set pin GP4 high
        GP5 = 0;         // Set pin GP5 low
        _delay(500000);  // 0.5 second delay
        GP4 = 0;         // Set pin GP4 low
        GP5 = 1;         // Set pin GP5 high
        _delay(500000);  // 0.5 second delay
    }
}
Posted in Uncategorized | Leave a comment

Minimum Viable Program for PIC12LF1572

Kevin Chubb (currently a final-year project student here in DIT) is designing a tiny robot using Microchip’s compact PIC12LF1572 microcontroller. It’s an interesting chip and Kevin’s doing great things with it. I decided to strip back one of the example programs he sent me just to find out exactly what’s required in the code to get a minimal program (flashing LED) working. In this example, I’m just blinking an LED twice a second on pin RA5 (pin 2). Thanks for the example code Kevin!

//
// MVP (minimum viable program) for PIC12LF1572
// Written by Ted Burke based on an example by Kevin Chubb
// Last updated 13-4-2017
//

#include <xc.h>

#pragma config FOSC = INTOSC    // Select INTOSC (internal) oscillator: I/O function on CLKIN pin
#pragma config WDTE = OFF       // Disable Watchdog Timer
#pragma config MCLRE = OFF      // Disable MCLR Pin (MCLR/VPP pin function is digital input)
#pragma config LVP = OFF        // Disable Low-Voltage Programming (High-voltage on MCLR/VPP must be used for programming)

int main(void)
{
    OSCCON = 0b01111010;  // 16 Mhz oscillator (optional)
    TRISAbits.TRISA5 = 0; // Make RA5 an output
    
    while(1)
    {
        LATAbits.LATA5 = 1; // LED on
        _delay(1000000);    // 250ms @ Fosc=16MHz
        LATAbits.LATA5 = 0; // LED off
        _delay(1000000);    // 250ms @ Fosc=16MHz
    }
}

This is the circuit:

I’m using a PICkit 2 programmer in Linux, so I used the pk2cmd command line application to transfer the program to the microcontroller. Unfortunately, the standard device file (PK2DeviceFile.dat) does not include the relatively recent PIC12LF1572, so I needed to download an edited version of the file from here:

http://github.com/GBert/misc/blob/master/pickit2/pk2cmd/pk2cmd/PK2DeviceFile.dat

Once I placed the updated PK2DeviceFile.dat file into my program’s folder, pk2cmd worked perfectly. These were the commands I used to build the code and program the microcontroller:

xc8 --chip=12LF1572 main.c
sudo pk2cmd -PPIC12LF1572 -M -F main.hex -T

If the location of pk2cmd is not included in the path, you’ll probably need to specify its location in the command.

Thai Phan pointed out in one of his comments below that you don’t need to run pk2cmd as root (as I did above, using “sudo”). You can configure udev so that all users have permission to access the PICkit 2. As Thai explained it:

Create a new file /etc/udev/rules.d/99-pickit2.rules containing the following:

SUBSYSTEM==”usb”, ENV{DEVTYPE}==”usb_device”, SYSFS{idVendor}==”04d8″, SYSFS{idProduct}==”0033″, MODE=”0666″

Then restart udev, as follows:

/etc/init.d/udev restart

Unplug your PICkit 2 and then plug it back in. It should now be possible to use pk2cmd without sudo. Thanks for the useful tip Thai Phan!

Finally, Kevin had quite a few additional configuration options at the beginning of his original example program. I’ll list them here because, although they weren’t required to get my example running, some of them presumably would be required in other situations. Here they are:

// Other configuration settings from Kevin's example that I didn't use:
#pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config PWRTE = OFF      // Power-up Timer disable
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF      // PLL Enable (4x PLL disabled)
#pragma config STVREN = OFF     // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOREN = OFF    // Low Power Brown-out Reset enable bit (LPBOR is disabled)

Thanks again to Kevin Chubb for the example code.

Posted in Uncategorized | Tagged , , , , , , , , , , , , , , | 6 Comments

dsPIC30F Quadrature Encoder Interface (QEI) – Basic Example

This video shows a basic example of using the Quadrature Encoder Interface (QEI) on Microchip’s dsPIC30F4011 microcontroller. I expect that the same approach will work with other microcontrollers in the dsPIC30F family.

In this example, I place two TCRT5000 reflective infrared sensors in front of a spinning black and white checkered disc to generate a pair of quadrature encoded signals. These signals are connected to pins QEA and QEB (the QEI input pins) on the dsPIC. The program shown in the example enables QEI so that the rotation of the disc is recorded in the POSCNT (position count) register. The value of POSCNT is printed via UART every 200 ms, so that it can be monitored on the PC screen.

This is the complete code:

//
// Quadrature Encoder Interface (QEI) example for dsPIC30F4011
// Written by Ted Burke, Last updated 12-4-2017
//

#include <xc.h>
#include <libpic30.h>
#include <stdio.h>
 
// Configuration settings
_FOSC(CSW_FSCM_OFF & FRC_PLL16); // Fosc=16x7.5MHz, i.e. 30 MIPS
_FWDT(WDT_OFF);                  // Watchdog timer off
_FBORPOR(MCLR_DIS);              // Disable reset pin
 
void main()
{
    // Use RD0 to blink an LED so that we can see program in running
    _TRISD0 = 0;
     
    // Setup UART so that we can monitor POSCNT value
    U1BRG = 48;            // 38400 baud @ 30 MIPS
    U1MODEbits.UARTEN = 1; // Enable UART
    
    // To use pins 6 and 7 as QEA and QEB (quadrature encoding inputs)
    // analog input must be disabled on both pins by setting the bits
    // for AN4 and AN5 in the ADPCFG register.
    _PCFG4 = 1;
    _PCFG5 = 1;
    
    // Enable the QEI module (x4 mode with POSCNT reset by MAXCNT match)
    _QEIM = 0b111;

    while(1)
    {
        // Print current value of position counter register
        printf("POSCNT = %d\n", POSCNT);
        
        _LATD0 = 1;         // LED on
        __delay32(3000000); // 100 ms
        _LATD0 = 0;         // LED off
        __delay32(3000000); // 100 ms
    }
}
Posted in Uncategorized | 1 Comment