Home | Blog | What's New? | Software | Raspberry Pi | Contact

PiGlow and BBC Basic

Whilst I was at the Cambridge Raspberry Jam I picked up a PiGlow from Pimoroni to play with. Obviously it was easy enough to get up and running with the example Python script, however as I was due to attend the RISC OS London Show I decided to get it up and running for RISC OS, and for simplicity I decided to use BBC Basic.

So what follows is a BBC Basic implementation of the example Python script that can be run on a Raspberry Pi running RISC OS (available free from RISC OS Open Limited and the main Raspberry Pi website's download pages.
For ease of use the BASIC file can be downloaded from here, where it can be extracted and run.

REM PiGlow
REM A BBC Basic program for driving the PiGlow device produced by
REM Pimoroni (http://pimoroni.com)
REM
REM Based on the example python script provided with the PiGlow
REM with additional information from the SN3218 data sheet
REM (also available from the Pimoroni website)

REM Setup an error handler to inform us what
REM line number an error occurs on
ON ERROR PROCError:END

REM Specify the IIC bus to use (There are two on the Raspberry Pi)
REM and some memory to build up the iic_transfer structure in
REM (See https://www.riscosopen.org/wiki/documentation/show/OS_IICOp)
IICBus% = 0
DIM IICTransfer% 16

REM The slave address of the PiGlow, as specified in the SN3218 datasheet
PiGlowAddress% = &54

REM Registers defined in the SN3218 datasheet that
REM are written to via IIC to control the PiGlow
ShutdownRegister% = &00
PWMRegister1% = &1
LEDControlRegister1% = &13
LEDControlRegister2% = &14
LEDControlRegister3% = &15
UpdateRegister% = &16
ResetRegister% = &17

REM Total number of LEDs available
numberOfLEDs% = 18

REM Array to store the IIC information we will be sending to update
REM the LEDs
DIM IICData% (numberOfLEDs% + 1)

REM Keep track of the brightness level of each LED
DIM LEDStates% numberOfLEDs%

REM Setup the sequence to follow. Starting from a low brightness to max
DIM sequence(numberOfLEDs%)

sequence() = &01, &02, &04, &08, &10, &18, &20, &30, &40, &50, &60, &70, &80, &90, &A0, &C0, &E0, &FF

REM Iniitialise the PiGlow ready for use
PROCSetupPiGlow

REM Default LEDs to the initial sequence
FOR I%=0 TO (numberOfLEDs%-1)
   LEDStates%?I% = sequence(I%)
NEXT I%

PROCUpdateLEDs(LEDStates%)

REPEAT

REM Rotate the sequence by 1. Moving the value that was at the start of the
REM sequence to the end
first% = LEDStates%?0

FOR I%=0 TO numberOfLEDs%-2
  LEDStates%?I% = LEDStates%?(I%+1)
NEXT I%
LEDStates%?(numberOfLEDs%-1) = first%

REM and update the LEDs to match the new sequence
PROCUpdateLEDs(LEDStates%)

REM Wait for 5 milliseconds before updating the sequence
PROCWait(5)

UNTIL FALSE

REM Shutdown the PiGlow
PROCStopPiGlow

END

DEF PROCSetupPiGlow
  REM Enable the PiGlow device
  IICData%?0=ShutdownRegister%
  IICData%?1=1
  PROCSendIIC(IICData%, 2)

  REM Turn on all the LEDs. The first byte will be written to
  REM LEDControlRegister1 and the second and third will automatically
  REM be written into the next bytes (LEDControlRegister2 and 3)
  REM Each register controls 6 LEDs (&7F sets the bottom 6 bits to 1,
  REM turning all the LEDs on)
  IICData%?0=LEDControlRegister1%
  IICData%?1=&7F
  IICData%?2=&7F
  IICData%?3=&7F
  PROCSendIIC(IICData%, 4)
ENDPROC

DEF PROCUpdateLEDs(leds)
  REM Start setting the LEDs from register 1. This means
  REM we will set all LEDs in sequence
  IICData%?0 = PWMRegister1%
  FOR I%=0 TO numberOfLEDs%
    IICData%?(I%+1) = leds?I%
  NEXT I%

  REM Send the new LED States to the PiGlow
  PROCSendIIC(IICData%, numberOfLEDs% + 1)

  REM and tell the PiGlow to update to display the new state
  IICData%?0=UpdateRegister%
  IICData%?1=&FF
  PROCSendIIC(IICData%, 2)
ENDPROC

DEF PROCSetLED(led, brightness)
  REM Sets the brightness of the specific LED
  REM we will set all LEDs in sequence
  REM led is from 0 to 17
  REM brightness is 0 to 255
  IICData%?0 = PWMRegister1% + led
  IICData%?1 = brightness

  REM Send the new LED States to the PiGlow
  PROCSendIIC(IICData%, 2)

  REM and tell the PiGlow to update to display the new state
  IICData%?0=UpdateRegister%
  IICData%?1=&FF
  PROCSendIIC(IICData%, 2)
ENDPROC

DEF PROCStopPiGlow
  REM Reset the PiGlow to its startup state (All LEDs off)
  IICData%?0=ResetRegister%
  IICData%?1=&00
  PROCSendIIC(IICData%, 2)
ENDPROC

DEF PROCSendIIC(data, length)
REM Setup the iic_transfer structure according to the documentation
IICTransfer%!0=(PiGlowAddress% << 1)
IICTransfer%!4=data
IICTransfer%!8=length
REM and send a single iic_transfer structure to the
REM requested IIC bus
SYS "OS_IICOp", IICTransfer%, ((IICBus% << 24) + 1)

ENDPROC

DEF PROCWait(period%)
  T%=TIME+period%
  REPEAT
  REM Wait for a key - We do this just to release the CPU
  X = INKEY 1
  UNTIL TIME > T%
ENDPROC


REM Our Error handler.  In case of errors in the code this
REM will tell us what line it occured on
DEF PROCError
ON ERROR OFF
REPORT
PRINT ERL
END
ENDPROC