Arduino Mega with Ethernet Shield + SPI ADC

Arduino Ethernet Shield + SPI ADC

Hello togehter,

Currently I’m working on a project on an Arduino Mega. I want to use an Ethernet shield (driver Chip: Wiz5500) in combination with an external 13 Bit ADC (Microchip MCP3304) and a LC-Display.

I created a sketch with 3 Timeslices, which are triggered by a Timer Interrupt. The interrupt Routine is executed 400 times per second.

Basically the Ethernet should listen to several Commands (Called SCPI_Commands). They were sended by an external PC as raw Strings over the TCP/IP Connection. I used the standard Ethernet setup with the Arduino Ethernet Library. The incoming SCPI_Command points on a Function, which the Arduino should execute. This part of code stands in the setup function. This Timeslice is called every 10 ms

In the second Timeslice print out the 8 Voltage Values on the display, which are measured by the external ADC in the third Timeslice.

The Ethernet part works fine if the SPI wires from the external ADC are not connected to the SPI Bus. The combination of both cause that it is not possible anymore to send commands to the System. Without the external ADC that works fine.
The connection via Putty seems to work fine as well, the error message occurs after sending the first command.

The strange thing for me is that I can trigger via Ethernet the Function MeaVol (that’s not the Function which is triggered in Timeslice 3). This function is triggered by the SCPI_Command :MEA:VOL and returns the Value of Chanel 0 of the external ADC. That works fine as well.

I know that there are several articles in different Forums but the only message that I found is that the Ethernetshield and the other SPI device need different CS Pins. In my case the CS for the Ethernet shield should be by default on Pin 10 and the CS for the ADC is on pin 49. The SS Pin (on the MEGA pin 53 is set to an OUTPUT but not used in my case.

I postet the Code below this text. I posted the Arduino Sketch and the library for the external ADC. To get the Values of the ADC the code in the library changes the SPI Settings a little bit maybe that could cause my Problems but I don’t think so.

My Questions are if anybody can help me with some ideas what could be wrong.

One another Question: Is it possible to use an Ethernet Shield with another SPI device or not.

Thanks for your Support.

That’s the Arduino Sketch

#include <Arduino.h>
#include <Ethernet.h>
#include “Vrekrer_scpi_parser.h”
#include “global_defs.h”
#include “MCP3304.h”
#include “LiquidCrystal_I2C.h”
#include “Wire.h”

//Beginning of Auto generated function prototypes by Atmel Studio
void Identify(SCPI_C commands, SCPI_P parameters, EthernetClient& client);
void SetBrightness(SCPI_C commands, SCPI_P parameters, EthernetClient& client);
void GetBrightness(SCPI_C commands, SCPI_P parameters, EthernetClient& client);
void MeaVol(SCPI_C commands, SCPI_P parameters, EthernetClient& client);
void IncDecBrightness(SCPI_C commands, SCPI_P parameters, EthernetClient& client);
void MeaTemp(SCPI_C commands, SCPI_P parameters, EthernetClient& client);
void TIM1_callback();
void MEA_VOL();
void printlcd();
//End of Auto generated function prototypes by Atmel Studio

byte mac = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 178, 177);
IPAddress myDns(0, 0, 0, 0);
IPAddress gateway(10, 11, 146, 254);
IPAddress subnet(255, 255, 252, 0);

MCP3304 adc(49);
EthernetServer server(23);
SCPI_Parser my_instrument;
LiquidCrystal_I2C lcd(0x27,16,2);

int brightness = 0;
const int ledPin = 9;
const int intensity[11] = {0, 3, 5, 9, 15, 24, 38, 62, 99, 159, 255};
int counters[NO_COUNTERS];
float Voltages[8];

void setup() {
lcd.begin();
pinMode(ledPin, OUTPUT);
Ethernet.begin(mac, ip);//, myDns, gateway, subnet);
server.begin();

my_instrument.RegisterCommand(F("*IDN?"), &Identify);
my_instrument.SetCommandTreeBase(F("SYSTem:ULtracap"));
my_instrument.RegisterCommand(F(":BRIGhtness"), &SetBrightness);
my_instrument.RegisterCommand(F(":BRIGhtness?"), &GetBrightness);
my_instrument.RegisterCommand(F(":BRIGhtness:INCrease"), &IncDecBrightness);
my_instrument.RegisterCommand(F(":BRIGhtness:DECrease"), &IncDecBrightness);
my_instrument.RegisterCommand(F(":MEA:VOL"),&MeaVol);
my_instrument.RegisterCommand(F(":MEA:TEMP"),&MeaTemp);

Serial.begin(115200);
Timer1.initialize(1000000UL/INTS_PER_SECOND); // Timer Interrupt every 2500µs → 400 Ints per Second…
Timer1.attachInterrupt(TIM1_callback);
pinMode(7,OUTPUT);
for (byte i = 0; i < NO_COUNTERS; i++)
{
counters[i] = -1;
}
}
void loop() {
if (counters[ETH_BUS] < 1) {
counters[ETH_BUS] = 4;
EthernetClient client = server.available();
if(client.connected()){
my_instrument.Execute(client);
}
}

if (counters[LC_Display] < 1) {
	counters[LC_Display] = 23 ;
	printlcd();
	
}
if (counters[ADConverter] < 1) {
	counters[ADConverter] = 10 ;
	MEA_VOL();
}

}

void Identify(SCPI_C commands, SCPI_P parameters, EthernetClient& client) {
client.println(F(“Vrekrer,Arduino SCPI Ethernet Instrument,#00,v0.4”));
}

void SetBrightness(SCPI_C commands, SCPI_P parameters, EthernetClient& client) {
if (parameters.Size() > 0) {
brightness = constrain(String(parameters[0]).toInt(), 0, 10);
analogWrite(ledPin, intensity[brightness]);
}
}

void GetBrightness(SCPI_C commands, SCPI_P parameters, EthernetClient& client) {
client.println(String(brightness, DEC));
}

void IncDecBrightness(SCPI_C commands, SCPI_P parameters, EthernetClient& client) {
String last_header = String(commands.Last());
last_header.toUpperCase();
if (last_header.startsWith(“INC”)) {
brightness = constrain(brightness + 1, 0, 10);
} else { // “DEC”
brightness = constrain(brightness - 1, 0, 10);
}
analogWrite(ledPin, intensity[brightness]);
}

void MeaVol(SCPI_C commands, SCPI_P parameters, EthernetClient& client) {
client.print("VOLTAGE = ");
client.println(adc.readSgl(0));
}
void MeaTemp(SCPI_C commands, SCPI_P parameters, EthernetClient& client) {
client.print("Temp = ");
client.println(adc.readSgl(1));
}

void TIM1_callback()
{
byte i = 0;

for (i = 0; i < NO_COUNTERS; i++)
{
	if (counters[i] > -1)
	counters[i]--;
}

}

void MEA_VOL(){
for(int i = 0; i<8;i++){
Voltages[i]=adc.readSgl(i);
}
}
void printlcd(){
lcd.setCursor(0,0);
lcd.print("V1 ");
lcd.print(Voltages[0],3);
lcd.setCursor(0,1);
lcd.print("V2 ");
lcd.print(Voltages[1],3);
}

that’s the read Function from the MCP3304 Library

int MCP3304::readAdc(int pin, boolean sgl) {

pin %= 8; //no more then 8 pins

SPI.setClockDivider(SPI_CLOCK_DIV16);	//Set Clockdivider for 1MHz SPI freq.

SPI.setBitOrder(MSBFIRST);		//set to most significatn bit first

SPI.setDataMode(SPI_MODE0); // SPI 0,0 as per MCP330x data sheet

byte configBits;

sgl ? configBits=0x0C : configBits=0x08; // 1100 for SGL mode, 1000 for DIFF mode

digitalWrite(_CS, LOW); //activate Chipselect

SPI.transfer(configBits | (pin >> 1)); //4bits 0, startbit, SGL/DIFF, 2 Channelbits (D2, D1)
byte hi = SPI.transfer(pin << 7); //lowest Channelbit (D0), rest dont care;return= first 2 returnbits undef, nullbit, Signbit, 4 highest databits
byte lo = SPI.transfer(0x00); //send dont care;return= 8 lowest databits

digitalWrite(_CS, HIGH); //deactivate Chipselect

byte sign = hi & 0x10;		//extract Sign Bit for DIFF

int adcValue = ((hi & 0x0f) << 8) + lo; //combinig the 2 return Values

if(sign){
adcValue -= 4096; //if CH- > CH+
}

SPI.setClockDivider(SPI_CLOCK_DIV4); //set back to default SPI speed

return adcValue;
}

Please edit your post and mark code correctly. You see yourself what the forum creates otherwise.

Sounds like a hardware problem but you failed to provide a wiring diagram and links to the exact boards you’re using. My guess at the moment is a not SPI compatible level converter but that’s wild guessing without additional information.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.