Send binary data by SPI

Questions and discussion about running MicroPython on a micro:bit board.
Target audience: MicroPython users with a micro:bit.
Post Reply
BruinBear
Posts: 27
Joined: Sat Jan 14, 2017 11:59 am

Send binary data by SPI

Post by BruinBear » Sat Jan 14, 2017 12:09 pm

I am trying to use an SPI 4 x 7-seg display to a BBC micro:bit. Everything is working fine except that, as a Python newbie, I don't know how to send 32 bits of binary data. The following code passes syntax:
[code]
# P.0 = BLK - turn display on/off (active low)
# P.1=LAT
from microbit import *
from microbit import spi
pin0.write_digital(0) #display on
spi.init(1000000,bits=8,mode=0, sclk=pin13, mosi=pin15, miso=pin14) #setup SPI
spi.write( '1234') #send 4 bytes to shift registers
pin1.write_digital(1) #latch data to display LEDs
sleep(1000)
while True: #toggle BLK to flash the display
pin0.write_digital(0)
sleep(500)
pin0.write_digital(1)
sleep(500)
[/code]

However, in the spi.write() line, I want to send the correct bit-pattern to light up the correct segments in the display. In Basic, I would convert the bits to bytes and send ike this:
[code]
let b0 = %11111110
let b1 = %00000000
let b2 = %00000000
let b3 = %00000000

spiout clk, dta, 0, (b0, b1, b2, b3)
[/code]

Please can someone tell me how to do this in Micropython, as I am getting nowhere? Thanks.

MODERATOR NOTE: I moved this to the micro:bit section of the forum.

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: Send binary data by SPI

Post by deshipu » Sat Jan 14, 2017 10:32 pm

There are several ways. The most compact would be to convert your binary numbers into hex numbers, and use:

Code: Select all

spi.write(b'\xfe\x00\x00\x00')
You can also send a bytearray:

Code: Select all

spi.write(bytearray([
    0b11111110,
    0b00000000,
    0b00000000,
    0b00000000,
]))

BruinBear
Posts: 27
Joined: Sat Jan 14, 2017 11:59 am

Re: Send binary data by SPI

Post by BruinBear » Sat Jan 14, 2017 10:57 pm

Thank you so much! Both methods work well on my 7-digit display. I was getting close, but couldn't quite get the syntax right.

BruinBear
Posts: 27
Joined: Sat Jan 14, 2017 11:59 am

Re: Send binary data by SPI

Post by BruinBear » Sun Jan 15, 2017 11:23 pm

More help needed, please!

The code below sets up a bytearray containing the bit patterns for each number 0-9 (plus decimal point) to be displayed on the 4x7-seg display (LSB is sent first). I can select a contiguous range of four numbers to be displayed e.g. in the example below spi.write(buf[0:4]) will display"3210".

I don't know how to select four non-contiguous numbers from the bytearray (e.g. if I want to display "5267", I would want to send the 6th, 3rd, 7th and 8th bit patterns from the array).

Thanks in advance for any help.

Code: Select all

# P.0 = BLK - turn display on/off (active low)
# P.1= LAT - latch data to display
# separate 4.5v supply for 7-seg
from microbit import *
from microbit import spi
pin0.write_digital(0) #turn display on
buf=bytearray([
    0b00111111,
    0b00000110,
    0b01011011,
    0b01001111,
    0b01100110,
    0b01101101,
    0b01111101,
    0b00000111,
    0b01111111,
    0b01101111,
    0b10000000,
    ]) #0123456789.
spi.init(baudrate=1000000,bits=8,mode=0, sclk=pin13, mosi=pin15, miso=pin14) #setup SPI
spi.write(buf[0:4]) #3210
pin1.write_digital(1) #latch data to display LEDs

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: Send binary data by SPI

Post by deshipu » Mon Jan 16, 2017 12:50 am

You can't do that with slicing. I think the easiest way would be to just make a second buffer, like this:

Code: Select all

output = bytearray(buf[d] for d in [5, 2, 6, 7])
spi.write(output)

BruinBear
Posts: 27
Joined: Sat Jan 14, 2017 11:59 am

Re: Send binary data by SPI

Post by BruinBear » Mon Jan 16, 2017 9:18 am

That's great @deshipu! Thanks again. I'm learning some useful Python :)

BruinBear
Posts: 27
Joined: Sat Jan 14, 2017 11:59 am

Re: Send binary data by SPI

Post by BruinBear » Mon Jan 16, 2017 9:24 pm

Thanks to help from deshipu, I have got the display working fully now with the BBC micro:bit. The code below just counts up to 9999 to show the operation (including adding leading zeros for numbers with fewer than 4 digits). It's not very useful as it is, but could easily be adapted to display sensor or other more useful data.

This display is very bright (non-multiplexed) and consumes up to 640mA, depending which segments are lit so can't be driven directly from the micro:bit. It would be possible to reduce the current consumption by using PWM on the BLK pin (at the cost of some brightness).

Code: Select all

#BBC micro:bit code to drive DSP-7S04 HW v2 SPI 4-digit 7-segment display
# P.0 = BLK - turn display on/off (active low)
# P.1=LAT - latch data onto the LEDs
# Any spare GPIO pins could be used for BLK and LAT
# Use separate 4.5v supply for 7-seg
# a
#f  b
# g
#e  c 
# d .[dp]

from microbit import *
from microbit import spi
pin0.write_digital(0) #display on
buf=bytearray([
    0b00111111,
    0b00000110,
    0b01011011,
    0b01001111,
    0b01100110,
    0b01101101,
    0b01111101,
    0b00000111,
    0b01111111,
    0b01101111,
    0b10000000,
    ]) #0123456789.
spi.init(baudrate=1000000,bits=8,mode=0, sclk=pin13, mosi=pin15, miso=pin14) #setup SPI

for displ_count in range(1,1000): #count up from 0 to 9999

    count_str="{0:0=4d}".format(displ_count) #turn into 4-digit str with leading spaces
    a=int(count_str[0]) #pick out each digit in turn 
    b=int(count_str[1]) #and turn back into integers
    c=int(count_str[2])
    d=int(count_str[3])
    
    #select the required bytes for each digit and create an output buffer
    output = bytearray(buf[e] for e in [d,c,b,a]) 
    spi.write(output) # output to 4-digit 7-seg (LSB first)
    pin1.write_digital(1) #latch data to display LEDs
    sleep(200)






WP_20170116_19_45_46_small.jpg
WP_20170116_19_45_46_small.jpg (45.57 KiB) Viewed 12155 times

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: Send binary data by SPI

Post by deshipu » Tue Jan 17, 2017 8:54 am

You should *really* add some resistors to limit the current. As it is you are risking damage to your microbit.

BruinBear
Posts: 27
Joined: Sat Jan 14, 2017 11:59 am

Re: Send binary data by SPI

Post by BruinBear » Tue Jan 17, 2017 9:21 am

The LEDs don't draw any current from the micro:bit. The micro:bit just sends the serial data to the two CAT4016 shift registers on the DSP-7S04 display module using SPI protocol. Each CAT4016 shift register is fitted with a current-limiting resistor.

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: Send binary data by SPI

Post by deshipu » Tue Jan 17, 2017 11:39 am

Ah, OK, you got me worried there.

Post Reply