Arduino  W/ E-net shield and Shiftbrite issues.

Today I received my products and started to hook them up. After loading some sample code from the Macetech site and wiring the shiftbrite to the shiftbrite shield they worked great. Now I’m trying to not use pins 10, 11, 12, & 13 for the shiftbrite because they are required for the Ethernet shield. So I modified the Macetech program for pins 3, 4, 5, & 6. Then rewired the LI, CI, EI, & DI pins leaving the Gnd and V+ on the shiftbrite shield. Once I loaded the modified program back into the Arduino the shiftbright let its smoke out. Below is a copy of the code I used. Do you know of a better way to use other outputs for this application? Any help would be greatly appreciated.

/* Ports and Pins

Direct port access is much faster than digitalWrite.
You must match the correct port and pin as shown in the table below.

Arduino Pin Port Pin
13 (SCK) PORTB 5
12 (MISO) PORTB 4
11 (MOSI) PORTB 3
10 (SS) PORTB 2
9 PORTB 1
8 PORTB 0
7 PORTD 7
6 PORTD 6
5 PORTD 5
4 PORTD 4
3 PORTD 3
2 PORTD 2
1 (TX) PORTD 1
0 (RX) PORTD 0
A5 (Analog) PORTC 5
A4 (Analog) PORTC 4
A3 (Analog) PORTC 3
A2 (Analog) PORTC 2
A1 (Analog) PORTC 1
A0 (Analog) PORTC 0

*/

// Defines for use with Arduino functions
#define clockpin 4 // CL
#define enablepin 5 // BL
#define latchpin 3 // XL
#define datapin 6 // SI

// Defines for direct port access
#define CLKPORT PORTD
#define ENAPORT PORTD
#define LATPORT PORTD
#define DATPORT PORTD
#define CLKPIN 4
#define ENAPIN 5
#define LATPIN 3
#define DATPIN 6

// Variables for communication
unsigned long SB_CommandPacket;
int SB_CommandMode;
int SB_BlueCommand;
int SB_RedCommand;
int SB_GreenCommand;

// Define number of ShiftBrite modules
#define NumLEDs 2

// Create LED value storage array
int LEDChannels[NumLEDs][3] = {0};

// Set pins to outputs and initial states void setup() {
pinMode(datapin, OUTPUT);
pinMode(latchpin, OUTPUT);
pinMode(enablepin, OUTPUT);
pinMode(clockpin, OUTPUT);
digitalWrite(latchpin, LOW);
digitalWrite(enablepin, LOW);
SPCR = (1<<SPE)|(1<<MSTR)|(0<<SPR1)|(0<<SPR0);
}

// Load values into SPI register
void SB_SendPacket() {

if (SB_CommandMode == B01) {
SB_RedCommand = 127;
SB_GreenCommand = 110;
SB_BlueCommand = 110;
}

SPDR = SB_CommandMode << 6 | SB_BlueCommand>>4;
while(!(SPSR & (1<<SPIF)));
SPDR = SB_BlueCommand<<4 | SB_RedCommand>>6;
while(!(SPSR & (1<<SPIF)));
SPDR = SB_RedCommand << 2 | SB_GreenCommand>>8;
while(!(SPSR & (1<<SPIF)));
SPDR = SB_GreenCommand;
while(!(SPSR & (1<<SPIF)));

}

// Latch values into PWM registers
void SB_Latch() {

delayMicroseconds(1);
LATPORT += (1 << LATPIN);
//ENAPORT += (1 << ENAPIN);
delayMicroseconds(1);
//ENAPORT &= ~(1 << ENAPIN);
LATPORT &= ~(1 << LATPIN);

}

// Send all array values to chain
void WriteLEDArray() {

SB_CommandMode = B00; // Write to PWM control registers

for (int i = 0; i<NumLEDs; i++) {
SB_RedCommand = LEDChannels*[0] & 1023;*
SB_GreenCommand = LEDChannels*[1] & 1023;
SB_BlueCommand = LEDChannels[2] & 1023;
SB_SendPacket();
_ }*_

* SB_Latch();*

* SB_CommandMode = B01; // Write to current control registers*

* for (int z = 0; z < NumLEDs; z++) SB_SendPacket(); *

* SB_Latch();*

}

// Fade between two colors at specified interval void fadeall(int rate, int fromred, int fromgreen, int fromblue, int tored, int togreen, int toblue) {

for (int i = 0; i < 33; i++) {

* for (int j1 = 0; j1 < NumLEDs; j1++) {*
_ LEDChannels[j1][0] = (fromred * (32 - i) + tored * i)/32;
LEDChannels[j1][1] = (fromgreen * (32 - i) + togreen * i)/32;
LEDChannels[j1][2] = (fromblue * (32 - i) + toblue * i)/32;
* }*_

* WriteLEDArray();*
* delay(rate);*

* } *
}

void loop() {

* fadeall(20,0,0,0,1023,0,0);*
* fadeall(20,1023,0,0,0,1023,0);*
* fadeall(20,0,1023,0,0,0,1023);*
* fadeall(20,0,0,1023,1023,0,0);*
* fadeall(20,1023,0,0,0,0,0);*

* delay(500);*
* fadeall(60,0,0,0,0,0,1023);*
* delay(500);*
* fadeall(60,0,0,1023,0,0,0);*
* delay(500);*

}

It's not possible to damage a ShiftBrite with code, so there is definitely a wiring issue you need to work out before testing anything else. Check really carefully that you don't have your power and ground crossed.

The main ShiftBrite demo code uses hardware SPI for the fastest performance. This interferes with Ethernet's SPI, naturally. Even if you change the pin assignments, the internal SPI hardware is on the same pins.

However, it's possible to move to different pins and use software SPI with good performance. You should use the example code here: non-hardware_spi_example [macetech documentation]

Thank you for the quick response. I believe I had it wired as follows:

V+ on V+ of Shiftbright shield
CI on DO4 under Extendershield
EI on DO5 under Extendershield
LI on DO 3 under Extendershield
DI on DO 6 under Extendershield
Gnd on Gnd of Shifbright shield

The example on non-hardware_spi_example [macetech documentation] shows using the default pins. Is the code I have above incorrect?

  • Mike

This is what I modifyed the code to be. The web interface works great. I’m not sure if i should try a shiftBright or not.

/* Ports and Pins

Direct port access is much faster than digitalWrite.
You must match the correct port and pin as shown in the table below.

Arduino Pin Port Pin
13 (SCK) PORTB 5
12 (MISO) PORTB 4
11 (MOSI) PORTB 3
10 (SS) PORTB 2
9 PORTB 1
8 PORTB 0
7 PORTD 7
6 PORTD 6
5 PORTD 5
4 PORTD 4
3 PORTD 3
2 PORTD 2
1 (TX) PORTD 1
0 (RX) PORTD 0
A5 (Analog) PORTC 5
A4 (Analog) PORTC 4
A3 (Analog) PORTC 3
A2 (Analog) PORTC 2
A1 (Analog) PORTC 1
A0 (Analog) PORTC 0

*/

// Ethernet Include
#include <Client.h>
#include <Ethernet.h>
#include <Server.h>
#include <spi.h>

// Ethernet variables
byte mac = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip = { 10, 248, 43, 111 };
byte gateway = { 10, 248, 43, 1 };
byte subnet = { 255, 255, 255, 0 };

// Ethernet Server Port
Server server(80);

// Defines for use with ShiftBrite Arduino functions
#define clockpin 4 // CL
#define enablepin 5 // BL
#define latchpin 3 // XL
#define datapin 6 // SI

// Defines for direct port access for ShiftBrite
#define CLKPORT PORTD
#define ENAPORT PORTD
#define LATPORT PORTD
#define DATPORT PORTD
#define CLKPIN 4
#define ENAPIN 5
#define LATPIN 3
#define DATPIN 6

// Variables for ShiftBright communication
unsigned long SB_CommandPacket;
int SB_CommandMode;
int SB_BlueCommand;
int SB_RedCommand;
int SB_GreenCommand;

// Define number of ShiftBrite modules
#define NumLEDs 3

// Create LED value storage array
int LEDChannels[NumLEDs][3] = {0};

// Set pins to outputs and initial states
void setup() {
// Ethernet Setup
Ethernet.begin(mac, ip, gateway, subnet);
server.begin();

// ShiftBrite Setup
pinMode(datapin, OUTPUT);
pinMode(latchpin, OUTPUT);
pinMode(enablepin, OUTPUT);
pinMode(clockpin, OUTPUT);
digitalWrite(latchpin, LOW);
digitalWrite(enablepin, LOW);
}

void SB_SendPacket() {

if (SB_CommandMode == B01) {
SB_RedCommand = 127;
SB_GreenCommand = 110;
SB_BlueCommand = 110;
}

SB_CommandPacket = SB_CommandMode & B11;
SB_CommandPacket = (SB_CommandPacket << 10) | (SB_BlueCommand & 1023);
SB_CommandPacket = (SB_CommandPacket << 10) | (SB_RedCommand & 1023);
SB_CommandPacket = (SB_CommandPacket << 10) | (SB_GreenCommand & 1023);

for (int j = 0; j < 32; j++) {
if ((SB_CommandPacket >> (31 - j)) & 1) {
DATPORT |= (1 << DATPIN);
}
else {
DATPORT &= ~(1 << DATPIN);
}
CLKPORT |= (1 << CLKPIN);
CLKPORT &= ~(1 << CLKPIN);
}
}

void SB_Latch() {

delayMicroseconds(1);
LATPORT |= (1 << LATPIN);
ENAPORT |= (1 << ENAPIN);
delayMicroseconds(1);
ENAPORT &= ~(1 << ENAPIN);
LATPORT &= ~(1 << LATPIN);

}

void WriteLEDArray() {

SB_CommandMode = B00; // Write to PWM control registers

for (int i = 0; i < NumLEDs; i++) {
SB_RedCommand = LEDChannels*[0];*
SB_GreenCommand = LEDChannels*[1];
SB_BlueCommand = LEDChannels[2];
SB_SendPacket();
_ }*_

* SB_Latch();*

* SB_CommandMode = B01; // Write to current control registers*
* for (int z = 0; z < NumLEDs; z++) SB_SendPacket();
SB_Latch();
_}
// Example loop to cycle all LEDs through primary colors*
void loop() {
* for (int i = 0; i < NumLEDs; i++) {
LEDChannels[0] = 1023;
LEDChannels[1] = 0;
LEDChannels[2] = 0;
}*_

* WriteLEDArray();*

* delay(200);*

* for (int i = 0; i < NumLEDs; i++) {*
_ LEDChannels*[0] = 0;
LEDChannels[1] = 1023;
LEDChannels[2] = 0;
}
WriteLEDArray();
delay(200);
for (int i = 0; i < NumLEDs; i++) {
LEDChannels[0] = 0;
LEDChannels[1] = 0;
LEDChannels[2] = 1023;
}
WriteLEDArray();*_

* // delay(200);*

* // Webserver Loop*
* Client client = server.available();*
* if (client) {*
* // an http request ends with a blank line*
* boolean current_line_is_blank = true;
_ while (client.connected()) {
if (client.available()) {
char c = client.read();
// if we’ve gotten to the end of the line (received a newline*

* // character) and the line is blank, the http request has ended,
// so we can send a reply*

* if (c == ‘\n’ && current_line_is_blank) {*
* // send a standard http response header*
* client.println(“HTTP/1.1 200 OK”);
client.println(“Content-Type: text/html”);
client.println();*_

* // output the value of each analog input pin*
* for (int i = 0; i < 6; i++) {*
* client.print("analog input ");*
* client.print(i);*
* client.print(" is ");*
* client.print(analogRead(i));*
* client.println("*
");
* }*
* // output the value of each digital output pin*
* for (int i = 0; i < 15; i++) {*
* client.print("digital output ");*
* client.print(i);*
* client.print(" is ");*
* client.print(digitalRead(i));*
* client.println("*
");
* }*
* // text output*
* client.println("*
");
* client.print(" Test Test Test");*
* break;*
* }*
* if (c == ‘\n’) {*
* // we’re starting a new line*
* current_line_is_blank = true;
_ } else if (c != ‘\r’) {
// we’ve gotten a character on the current line*

* current_line_is_blank = false;*
* }
}
}
// give the web browser time to receive the data*

* delay(1);
client.stop();
}*_

}

Looks good, I would double check all the connections one last time, and try another ShiftBrite!

So double checked my wires and it works this time… Then I left it on last night and when I can in this morning the e-net card was not flashing or responding to a ping. The shiftbrits were still flashing. So i then reverted to the basic e-net code that was in it before. now only the pwr and link lights are on. when i left last night the tx and rx lights were flashing. Any ideas as to what happened?

  • Mike

#include <Client.h>
#include <Ethernet.h>
#include <Server.h>
#include <spi.h>

byte mac = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip = { 10, 248, 43, 111 };
byte gateway = { 10, 248, 43, 1 };
byte subnet = { 255, 255, 255, 0 };

Server server(80);

void setup()
{
Ethernet.begin(mac, ip, gateway, subnet);
server.begin();

}

void loop()
{
Client client = server.available();
if (client) {
// an http request ends with a blank line
boolean current_line_is_blank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// if we’ve gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so we can send a reply
if (c == ‘\n’ && current_line_is_blank) {
// send a standard http response header
client.println(“HTTP/1.1 200 OK”);
client.println(“Content-Type: text/html”);
client.println();

// output the value of each analog input pin
for (int i = 0; i < 6; i++) {
client.print("analog input “);
client.print(i);
client.print(” is “);
client.print(analogRead(i));
client.println(”
");
}
// output the value of each digital output pin
for (int i = 0; i < 15; i++) {
client.print("digital output “);
client.print(i);
client.print(” is “);
client.print(digitalRead(i));
client.println(”
“);
}
// text output
client.println(”
“);
client.print(” IS THIS COOL OR WHAT… ");
break;
}
if (c == ‘\n’) {
// we’re starting a new line
current_line_is_blank = true;
} else if (c != ‘\r’) {
// we’ve gotten a character on the current line
current_line_is_blank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
client.stop();
}

}

Never mind, I guess the office had a power outage last night and fried the port on my hub I was using. After plugging the e-net card directly into the network it started to work. Thank you for your patience and assistance.

Is it possible to run two void loops at the same time? I would like to run the code more efficiently and allow the user to chance the colors via a website. Any help would be appreciated.

Thank you,
Mike Legg

Is it possible to run two void loops at the same time?

No that's silly.

However you perfectly well can have two calls to a procedure in the loop() so what would be the difference?