Go Down

Topic: Req: Controlling Nexus B08M04N 4 Digit LED display module via SPI - Help please (Read 1 time) previous topic - next topic

Dave67

Hi!

I've done bit of PIC programming previously, but this is my first foray into Arduino, and first forum posting, so please be gentle with me!  :~

I've got an old Nexus B08MO4N 4x 7-segment LED display, and I'm trying to drive it using the Arduino Uno and SPI library, from the Arduino 1.0 IDE running on a Windows XP laptop.

The data sheet for the Nexus display is here:
http://paginas.fe.up.pt/~hmiranda/st2/serial_display.pdf

The Nexus display requires a single clock (typically 500 Khz) and single data inputs. No data outputs.
The Chip Enable is wired to ground ("enable").

The data protocol is:
MSB first
Triggered on rising edge of clock
Clock is idle when low

36 bits of data as follows:
Bit 0 when set to "1" is the start bit
The subsequent 8 bits (1-8) define whether segments a-g and the decimal point are on or off for Digit 1 (Right hand position)
The next 24  bits (9-32) are similar for Digits 2-4
Bits 33 & 34 light additional LEDs if set to "1"
Bit 36 when set to "0" is the Null ("end of data") bit.

I've had a go at using SPI library to send a simple test message "1234" to the display.

I've only used the "MOSI" fuctions of the SPI library, since the Nexus only has inputs: there is no returning "SOMI" signal from the display to the Arduino.

The code compiles OK, but the display remains blank when I run the sketch
(It's not a hardware issue - the display works fine when not connected to the Arduino!)

I'm sure I've made some basic error in my use of the SPI library, or with the Processing language, and would be very grateful for your advice & help

Many thanks in anticipation

Dave
(UK)

(Sketch attached)

Nick Gammon


I've only used the "MOSI" fuctions of the SPI library, since the Nexus only has inputs: there is no returning "SOMI" signal from the display to the Arduino.


It's called MISO (master in, slave out).

Try here:

http://www.gammon.com.au/forum/?id=11524

I was driving a 4 x 7 segment LED with SPI.

Quote
The code compiles OK, but the display remains blank when I run the sketch


Perhaps show your code?

Nick Gammon


I've only used the "MOSI" fuctions of the SPI library, since the Nexus only has inputs


You can't "only use MOSI". Each SPI transfer transfers data two ways. You can ignore the return value if you want to.

http://www.gammon.com.au/spi

Dave67

Hi Nck

Thanks for your reply.

>>It's called MISO (master in, slave out)
Sorry. Blame dyslexia, or confusion with Japanese soup... ;)

>>Perhaps show your code?
Apologies. I thought I'd attached the code to my previous posting - I've cut and pasted the listing below.

Thanks for the link and your elegant solution to a similar problem.

My problem is more specific.
I want to send a 36 bit "word" of data along with a clock signal to a specific serial 4 digit LED display device; only updating intermittently at non-regular intervals (the Nexus module doesn't care about receiving regular updates; it just continues to display the efects of the last received packet of data until the next one arrives).

With a bit of time and effort I reckon I could write a bespoke routine specifically to toggle a clock signal at one output pin of the Arduino, and send the data from a second pin; but on looking through the Arduino web sites, I came across the SPI library, and figured that this might be a ready-made and more elegant way of sending clock and data signals in one direction.
The exercise would also be a useful introduction into understanding how to use the SPI library for more complex applications in future (e.g. 2-way communication with an EEPROM).

I've seen fairly complex examples of how to use the SPI commands to achieve 2-way communication with other devices like EPROMS and memory cards; however as I am only planning to send data in one direction (from Arduino to LED display), I need to know what elements of the SPI instructions I can ignore as "surplus to requirements" to keep my code neat, but still have the correct instructions for 1-way transmission of data.  

I'd be very grateful for your advice on my sketch and correction of errors.

Hope this makes sense - please let me know if you need further information or explanation.

Many thanks

Dave

(sketch pasted below)
======================================================================================


Code: [Select]
#include <SPI.h>

// Title: Nexus B08M04N Synchronous Serial 4 Digit LED module data test
// Author: Dave Williams 5 May 2012
// Action: To send "1234" to 4 segment LED display

// Nexus Display Pin Connections: 3 = Enable (0v);4 = Data;5 = Clock; 6 = 5V; 8 = Gnd (0v)
// 500kHz max data transfer rate

// Define Arduino output pins
#define DATAOUT 11   //Master Out-Slave In (MOSI) from Arduino pin 11 to Nexus Data In pin 4
#define SPICLOCK  13// Serial Clock (sck) from Arduino pin 13 to Nexus pin 5

// Define LED segments a-g & decimal point to be lit by hex codes corresponding to decimal numbers 0 - 9 :
// LOOKUP Digit[0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6]

// set up data buffer to hold 6 bytes of data representing start code, 4 digit codes, and finish code
char buffer [6];

void fill_buffer()
{
buffer [0] = 0x01; //start bit  "1" to indicate start of data - i.e.
buffer [1] = 0x66; // 1st (RH) digit = "4"
buffer [2] = 0xF2; // 2nd digit = "3"
buffer [3] = 0xDA; // 3rd digit = "2"
buffer [4] = 0x60; // 4th (LH) digit = "1"
buffer [5] = 0x00; // 0 = LED1 off, 0 = LED2 off, then 0 to indicate end of data - i.e. 000xxxxx
}

void setup()
{
 Serial.begin(9600); // Initiate Serial data transmission

 pinMode(DATAOUT, OUTPUT);   // Define Arduino MOSI & SCK pins as Outputs
 pinMode(SPICLOCK,OUTPUT);

 SPCR = 01010011;
 // interrupt disabled,spi enabled,msb first,Arduino = master,clk low when idle,
 // sample on leading edge of clk,system clock rate "3" (slowest; 250KHz)
}

void loop()
{
// Clear SPI status and data registers to remove any spurious data from previous runs
 SPSR = 0;
 SPDR = 0;
 delay(10);

// call routine to fill buffer with data
fill_buffer();

// send all 6 data bytes in sequence to Nexus LED display, MSB first; with clock signal
 for (int I=0;I=5;I++)
 {
   SPI.transfer(buffer[I]);
 }
delay(500);
}



Moderator edit: [code] ... [/code] tags added. (Nick Gammon)

Dave67

Hi

Still no joy getting the SPI library to send synchronous serial data to the Nexus LEDs

Can anyone please tell me what is wrong with my sketch, and how to achieve the result I want using the SPI library?

I've also tried sending data via a "brute force" technique of directly toggling the output pins of the Arduino to generate the clock and data signal (listing pasted below).
I estimate that the output frequency that I'm achieving with this method is a little lower than the 500kHz max speed of the Nexus; but I'm not sure how to calculate how long it takes the Arduino to perform each of the instructions (any tips?).

This approach doesn't seem to work either - no response from the LEDs.
?am I trying to toggle the output pins of the Arduino faster than they can respond?

Again, for my education, please explain where I've gone wrong with this sketch.

Many thanks

Dave

===============================================================

Code: [Select]
// Title: Nexus B08M04N Synchronous Serial 4 Digit LED module data test
// Author: Dave Williams 5 May 2012
// Action: To send "1234" to 4 segment LED display - "Brute force" bitwise method!

// Nexus Display Pin Connections: 3 = Enable (0v);4 = Data;5 = Clock; 6 = 5V; 8 = Gnd (0v)
// 500kHz max data transfer rate


void setup()
{
// Define Arduino output pins
#define DATA 10   //Data from Arduino pin 10 to Nexus Data In pin 4
#define CLOCK 11 // Serial Clock from Arduino pin 11 to Nexus pin 5

// Define LED segments a-g + decimal point to be lit by hex codes corresponding to decimal numbers 0 - 9 :
// LOOKUP Digit[0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6]

pinMode(DATA, OUTPUT);   // Define Clock & Data pins as digital Outputs
pinMode(CLOCK, OUTPUT);

int x = 0;
}

void loop()
{
//fill buffer with data
int buffer[4] = {0x66,0xF2,0xDA,0x60};

//buffer[0] = 0x66; // 1st (RH) digit = "4"
//buffer[1] = 0xF2; // 2nd digit = "3"
//buffer[2] = 0xDA; // 3rd digit = "2"
//buffer[3] = 0x60; // 4th (LH) digit = "1"

// send "START" bit ("1") down the DATA line with a clock pulse down the CLOCK line
 digitalWrite(DATA,HIGH);  
 digitalWrite (CLOCK,HIGH); //start clock pulse
 delayMicroseconds(2);  //500KHz = 1 clock pulse every 2 microseconds
 digitalWrite(CLOCK,LOW);//end clock pulse

// send all 4 data bytes in sequence to Nexus LED display, MSB first
 
 for (int I=0;I=3;I++){ // Look at each data byte in turn from byte 0 to 3
 int (x) = buffer[I];
 for (int y=7;y=0;y--){ // test bits in data from MSB (7) to LSB (0)
 
 
 if (bitRead(x,y) == 1)
 {
 digitalWrite(DATA,HIGH); //If data bit 'y' set, then send a data pulse with clock pulse
 }
 else
 {
 digitalWrite(DATA,LOW);  //If data bit 'y' clear, then send no data pulse with clock pulse
 }
 digitalWrite (CLOCK,HIGH); //start clock pulse
 delayMicroseconds(2);  //500KHz = 1 clock pulse every 2 microseconds
 digitalWrite(CLOCK,LOW);//end clock pulse
 
 } //loop to test next bit
 } //loop to test next byte
 
// Send 2 LED bits & STOP bit "0 0 0"
for (int I=0;I=2;I++){
 digitalWrite(DATA,LOW);  
 digitalWrite (CLOCK,HIGH); //start clock pulse
 delayMicroseconds(2);  //500KHz = 1 clock pulse every 2 microseconds
 digitalWrite(CLOCK,LOW);//end clock pulse
}

delay(1000);
}



Moderator edit: [code] ... [/code] tags added. (Nick Gammon)

Go Up