Send binary data by SPI
Send binary data by SPI
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.
[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.
Re: Send binary data by SPI
There are several ways. The most compact would be to convert your binary numbers into hex numbers, and use:
You can also send a bytearray:
Code: Select all
spi.write(b'\xfe\x00\x00\x00')
Code: Select all
spi.write(bytearray([
0b11111110,
0b00000000,
0b00000000,
0b00000000,
]))
Re: Send binary data by SPI
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.
Re: Send binary data by SPI
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.
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
Re: Send binary data by SPI
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)
Re: Send binary data by SPI
That's great @deshipu! Thanks again. I'm learning some useful Python
Re: Send binary data by SPI
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).
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)
Re: Send binary data by SPI
You should *really* add some resistors to limit the current. As it is you are risking damage to your microbit.
Re: Send binary data by SPI
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.
Re: Send binary data by SPI
Ah, OK, you got me worried there.