The problem is, I am running a WiFi shield between the arduino uno and this temperature sensor. Whenever I connect SDO from the barometric sensor to pin12, as the code suggests, the WiFi shield is unable to connect to my network.
After some reverse engineering of the code and reading up on the SPI interface, it seems that pin 12 (and 10+11+13) are reserved for communication between the arduino uno and the WiFi shield. Does this mean I cannot use them for anything else? I can also see that pin 7 is used for handshake and pin 4 is used for the SD card. Can it be that the WiFi shield occupies half of my digital pins?
So now I am looking for a workaround. With the other sensors connected (light, temperature 2x, humidity, wind speed, wind direction, and rain) I am running out of pins. I did some exercises in the Arduino starter kit that talked about using a shift register to allow you to connect multiple inputs to one digital pin. Can I use a shift register for pin 12 as well, to keep the barometric sensor from interfering with the WiFi shield?
Can I use a shift register for pin 12 as well, to keep the barometric sensor from interfering with the WiFi shield?
No.
That sensor is an SPI device, like the WiFi shield. You can use multiple SPI devices on the Arduino, simultaneously, as long as each one has a separate chip/slave select pin. You can connect the sensors chip select pin to any unused pin, and set that pin LOW to activate the sensor and HIGH to deactivate it.
After some reverse engineering of the code and reading up on the SPI interface, it seems that pin 12 (and 10+11+13) are reserved for communication between the arduino uno and the WiFi shield. Does this mean I cannot use them for anything else? I can also see that pin 7 is used for handshake and pin 4 is used for the SD card. Can it be that the WiFi shield occupies half of my digital pins?
6 of 20 is not quite half. The analog pins can be used as digital pins, too.
Thanks for the reply! I was not aware you could use analog pins as digital. Great!
This particular barometric sensor uses, as far as I can understand, three SPI pins: SDI, SDO and SCK. By messing around with it, it seems that only SDO is affecting the WiFi shield. Is this the only one I need to remap?
In my code, pasted below, I never set pins 11, 12 or 13. I'm having a hard time understanding what is going on, but I think it somehow selects these three pins as they are the default SPI pins. Where and how would I make it use other pins?
/*
MPL115A1 sparkfun breakout baropressure meter
SDN : pin 6
CSN : pin 9
SDI/MOSI : pin 11
SDO/MISO : pin 12
SCK : pin 13
*/
#include <WiFi.h>
#include <SPI.h>
//==============================//
// Set Pins //
//==============================//
const int PinBaroShutDown = 6; // MPL115A1 Connected to SDN on barometer
const int PinBaroChipSelectPin = 9; // MPL115A1 Connected to CSN on barometer
const long UpdateInterval = 2000; // Update interval for post to server in milliseconds
//==============================//
// Variables //
//==============================//
float pressure; // Initialize sensor value: Pressure in hecto-pascal
char wifiSSID[] = "ssid";
char wifiPass[] = "password";
//==============================//
// For barometric sensor //
//==============================//
#define PRESH 0x80
#define PRESL 0x82
#define TEMPH 0x84
#define TEMPL 0x86
#define A0MSB 0x88
#define A0LSB 0x8A
#define B1MSB 0x8C
#define B1LSB 0x8E
#define B2MSB 0x90
#define B2LSB 0x92
#define C12MSB 0x94
#define C12LSB 0x96
#define CONVERT 0x24
float A0_;
float B1_;
float B2_;
float C12_;
//==============================//
// Setup() //
//==============================//
void setup()
{
// Initialize serial
Serial.begin(9600);
// start the SPI library:
SPI.begin();
// Set pin modes
pinMode(PinBaroShutDown, OUTPUT);
digitalWrite(PinBaroShutDown, HIGH);
pinMode(PinBaroChipSelectPin, OUTPUT);
digitalWrite(PinBaroChipSelectPin, HIGH);
delay (10);
// read barometer registers that contain the chip-unique parameters to do the math
unsigned int A0H = readRegister(A0MSB);
unsigned int A0L = readRegister(A0LSB);
A0_ = (A0H << 5) + (A0L >> 3) + (A0L & 0x07) / 8.0;
unsigned int B1H = readRegister(B1MSB);
unsigned int B1L = readRegister(B1LSB);
B1_ = ( ( ( (B1H & 0x1F) * 0x100)+B1L) / 8192.0) - 3 ;
unsigned int B2H = readRegister(B2MSB);
unsigned int B2L = readRegister(B2LSB);
B2_ = ( ( ( (B2H - 0x80) << 8) + B2L) / 16384.0 ) - 2 ;
unsigned int C12H = readRegister(C12MSB);
unsigned int C12L = readRegister(C12LSB);
C12_ = ( ( ( C12H * 0x100 ) + C12L) / 16777216.0 ) ;
}
//==============================//
// Loop() //
//==============================//
void loop()
{
if (status != WL_CONNECTED) //If not connected to WiFi
connectWifi();
else {
pressure = getPressure(); // Pressure in hPa
Serial.print("Pressure: ");
Serial.println(pressure);
delay(UpdateInterval);
}
}
float getPressure()
{
// Returns a pressure reading in hPa
digitalWrite(PinBaroChipSelectPin, LOW);
delay(3);
SPI.transfer(0x24);
SPI.transfer(0x00);
digitalWrite(PinBaroChipSelectPin, HIGH);
delay(3);
digitalWrite(PinBaroChipSelectPin, LOW);
SPI.transfer(PRESH);
unsigned int presH = SPI.transfer(0x00);
delay(3);
SPI.transfer(PRESL);
unsigned int presL = SPI.transfer(0x00);
delay(3);
SPI.transfer(TEMPH);
unsigned int tempH = SPI.transfer(0x00);
delay(3);
SPI.transfer(TEMPL);
unsigned int tempL = SPI.transfer(0x00);
delay(3);
SPI.transfer(0x00);
delay(3);
digitalWrite(PinBaroChipSelectPin, HIGH);
unsigned long press = ((presH *256) + presL)/64;
unsigned long temp = ((tempH *256) + tempL)/64;
float pressure = A0_+(B1_+C12_*temp)*press+B2_*temp;
float preshPa = (pressure* (65.0/1023.0)+50.0) * 10;
return(preshPa);
}
unsigned int readRegister (byte thisRegister)
{
//Read registers in barometer
unsigned int result = 0; // result to return
digitalWrite(PinBaroChipSelectPin, LOW);
delay(10);
SPI.transfer(thisRegister);
result = SPI.transfer(0x00);
digitalWrite(PinBaroChipSelectPin, HIGH);
return(result);
}
void connectWifi()
{
// Connects the arduino to a WPA2 WiFi network
}
This particular barometric sensor uses, as far as I can understand, three SPI pins: SDI, SDO and SCK. By messing around with it, it seems that only SDO is affecting the WiFi shield. Is this the only one I need to remap?
You can't. The SPI pins are fixed in hardware. As I said, you can have any number of devices connected to the SPI pins at one time, as long as each has a separate slave/chip select pin.
The WiFi shield uses pin 10 as the slave select pin. The pressure sensor can use any unused pin as it's slave select pin (as long as the corresponding pin on the pressure sensor is connected to that pin on the Arduino).
In my code, pasted below, I never set pins 11, 12 or 13.
This particular barometric sensor uses, as far as I can understand, three SPI pins: SDI, SDO and SCK. By messing around with it, it seems that only SDO is affecting the WiFi shield. Is this the only one I need to remap?
You can't. The SPI pins are fixed in hardware. As I said, you can have any number of devices connected to the SPI pins at one time, as long as each has a separate slave/chip select pin.
The WiFi shield uses pin 10 as the slave select pin. The pressure sensor can use any unused pin as it's slave select pin (as long as the corresponding pin on the pressure sensor is connected to that pin on the Arduino).
Again, thanks for the reply!
Hmmm... I am currently using the following pins for my barometric sensor:
pin8 as sleep/shutdown
pin9 as chip select
pin11 as serial data in
pin12 as serial data out
pin13 as serial clock
Shouldn't this in theory work fine with the wifi shield? Any tips on troubleshooting this?
Okay, here it goes, this is my complete code. (trimmed to match the 9500 max characters of forum posts) Also bare in mind that this is my first Arduino code ever, so any suggestions are highly appreciated
#include <WiFi.h>
#include <SPI.h>
#include <TextFinder.h>
#include <OneWire.h>
//==============================//
// Set Pins //
//==============================//
const int PinTempIn = A0; // TMP36 Inside temperature sensor (sparkfun.com/products/10988)
const int PinLight = A1; // Temt6000 Outside light sensor (sparkfun.com/products/8688)
const int PinHumid = A2; // HIH-4030 Outsude humidity sensor (sparkfun.com/products/9569)
const int PinVane = A5; // SEN-08942 Wind vane (wind direction) (sparkfun.com/products/8942)
const int PinAnemometer = 2; // SEN-08942 Wind speed pin (interupt) (sparkfun.com/products/8942)
const int PinRainMeter = 3; // SEN-08942 Rain meter (interupt) (sparkfun.com/products/8942)
const int PinTempOut = 5; // DS18B20 Outside temperature sensor signal pin (sparkfun.com/products/11050)
const int PinBaroShutDown = 6; // MPL115A1 Connected to SDN on barometer (sparkfun.com/products/9721)
const int PinWiFiDoNotUse = 7; // DEV11287 Reminder to not use. Already used by WiFi hadshake (sparkfun.com/products/11287)
const int PinLEDpost = 8; // LED That turns red if post to server was unsuccessful
const int PinBaroChipSelectPin = 9; // MPL115A1 Connected to CSN on barometer
const int PinWifiDoNotUse2 = 10; // DEV11287 Reminder to not use. Already used by WiFi chip select (sparkfun.com/products/11287)
//==============================//
// Config //
//==============================//
char wifiSSID[] = "a"; // Network SSID
char wifiPass[] = "b"; // Network password
char server[] = "c"; // Server of the target php script
char url[] = "d"; // Local server URL to php script
char serverSecret[] = "e"; // Secret for posting data to php script on the server
char location[] = "f"; // Name of location
float latitude = 1.1; // Latitude of location
float longitude = 2.2; // Longitude of location
const long UpdateInterval = 10000; // Update interval for post to server in milliseconds
//==============================//
// Interupt Cpunters //
//==============================//
volatile int numRevsAnemometer = 0; // Incremented in the interrupt of pulse from wind speed sensor
volatile int numRainClicks = 0; // Incremented in the interrupt of pulse from rain sensor
//==============================//
// Initialize variables //
//==============================//
float tempIn;
float tempOut;
int light;
float rHumidity;
float pressure;
String wind_direction;
float wind_speed;
float rainfall;
WiFiClient client;
TextFinder finder(client);
OneWire ds(PinTempOut); // Initialise the outside temperature sensor
int status = WL_IDLE_STATUS;
//==============================//
// For barometric sensor //
//==============================//
#define PRESH 0x80
#define PRESL 0x82
#define TEMPH 0x84
#define TEMPL 0x86
#define A0MSB 0x88
#define A0LSB 0x8A
#define B1MSB 0x8C
#define B1LSB 0x8E
#define B2MSB 0x90
#define B2LSB 0x92
#define C12MSB 0x94
#define C12LSB 0x96
#define CONVERT 0x24
float A0_;
float B1_;
float B2_;
float C12_;
void setup()
{
// Initialize serial
Serial.begin(9600);
// start the SPI library:
SPI.begin();
// Set pin modes
pinMode(PinLEDpost, OUTPUT);
pinMode(PinRainMeter, INPUT);
digitalWrite(PinRainMeter, HIGH);
pinMode(PinAnemometer, INPUT);
digitalWrite(PinAnemometer, HIGH);
pinMode(PinBaroShutDown, OUTPUT);
digitalWrite(PinBaroShutDown, HIGH);
pinMode(PinBaroChipSelectPin, OUTPUT);
digitalWrite(PinBaroChipSelectPin, HIGH);
delay (10);
// Initialize interupts
attachInterrupt(0, countAnemometer, FALLING);
attachInterrupt(1, countRainClicks, FALLING);
// read barometer registers that contain the chip-unique parameters to do the math
unsigned int A0H = readRegister(A0MSB);
unsigned int A0L = readRegister(A0LSB);
A0_ = (A0H << 5) + (A0L >> 3) + (A0L & 0x07) / 8.0;
unsigned int B1H = readRegister(B1MSB);
unsigned int B1L = readRegister(B1LSB);
B1_ = ( ( ( (B1H & 0x1F) * 0x100)+B1L) / 8192.0) - 3 ;
unsigned int B2H = readRegister(B2MSB);
unsigned int B2L = readRegister(B2LSB);
B2_ = ( ( ( (B2H - 0x80) << 8) + B2L) / 16384.0 ) - 2 ;
unsigned int C12H = readRegister(C12MSB);
unsigned int C12L = readRegister(C12LSB);
C12_ = ( ( ( C12H * 0x100 ) + C12L) / 16777216.0 ) ;
}
void loop()
{
if (status != WL_CONNECTED) //If not connected to WiFi
connectWifi();
else {
tempIn = getTempIn(); // Temperature inside in celcius
tempOut = getTempOut(); // Temperature outside in celsius
light = getLight(); // 0-1023. Need to translate into useful info
pressure = getPressure(); // Pressure in hPa
wind_direction = getWindDirection(); // Wind direction in one or two character string (N, NE, ...)
wind_speed = getWindSpeed(); // Wind speed in meters per second
rainfall = getRain(); // Rain in millimeters
rHumidity = getRelativeHumidity(tempOut); // Relative humidity in percentage
postToServer();
}
delay(UpdateInterval);
}
float getTempIn()
{
// Returns the temperature from the SEN-10988 outside thermometer in DEG Celsius
}
float getTempOut()
{
// Returns the temperature from the DS18S20 outside thermometer in DEG Celsius
}
int getLight()
{
// Returns a 0-1023 value for light measured on the Temt6000 light sensor
}
String getWindDirection()
{
// Returns a string representing the direction that the wind vane is pointing at
}
float getWindSpeed()
{
// Returns a wind speed in meters per second from the anemometer
}
float getRelativeHumidity (float degreesCelsius)
{
// Returns a relative air humidity based on measurement from outside temperature sensor in percentage
}
float getPressure()
{
// Returns a pressure reading in hPa
digitalWrite(PinBaroChipSelectPin, LOW);
delay(3);
SPI.transfer(0x24);
SPI.transfer(0x00);
digitalWrite(PinBaroChipSelectPin, HIGH);
delay(3);
digitalWrite(PinBaroChipSelectPin, LOW);
SPI.transfer(PRESH);
unsigned int presH = SPI.transfer(0x00);
delay(3);
SPI.transfer(PRESL);
unsigned int presL = SPI.transfer(0x00);
delay(3);
SPI.transfer(TEMPH);
unsigned int tempH = SPI.transfer(0x00);
delay(3);
SPI.transfer(TEMPL);
unsigned int tempL = SPI.transfer(0x00);
delay(3);
SPI.transfer(0x00);
delay(3);
digitalWrite(PinBaroChipSelectPin, HIGH);
unsigned long press = ((presH *256) + presL)/64;
unsigned long temp = ((tempH *256) + tempL)/64;
float pressure = A0_+(B1_+C12_*temp)*press+B2_*temp;
float preshPa = (pressure* (65.0/1023.0)+50.0) * 10;
return(preshPa);
}
float getRain()
{
// Returns rain measured in last period in millimeters
}
void connectWifi()
{
// Connects the arduino to a WPA2 WiFi network as defined above
// attempt to connect using WPA2 encryption:
Serial.println("Attempting to connect to WPA network...");
status = WiFi.begin(wifiSSID, wifiPass);
// wait for connection:
delay(5000);
// if you're not connected, stop here:
if ( status != WL_CONNECTED) {
Serial.println("Couldn't get a wifi connection");
Serial.println();
}
// if you are connected, print out info about the connection:
else {
Serial.print("Connected to network ");
Serial.println(wifiSSID);
Serial.println();
}
}
void postToServer()
{
// Posts results to URL as defined above
}
void countAnemometer()
{
// Helper method for the interupt of wind speed. Called each time the reed switch triggers (one revolution).
}
unsigned int readRegister (byte thisRegister)
{
//Read registers in barometer
unsigned int result = 0; // result to return
digitalWrite(PinBaroChipSelectPin, LOW);
delay(10);
SPI.transfer(thisRegister);
result = SPI.transfer(0x00);
digitalWrite(PinBaroChipSelectPin, HIGH);
return(result);
}
void countRainClicks()
{
// Interrupt handler for rain meter. Called each time the bucket tips
}
Your function to get the data from the barometric sensor correctly toggles the chip select pin for that sensor BUT it fails to set the other chip select pin, for the other the SPI device. It needs to set pin 10 HIGH and LOW at the appropriate times. I can never remember whether it is HIGH to activate or to deactivate. Set pin 10 HIGH at the start of the function, and LOW at the end. If that doesn't work, change which way the pin is set at the start and the end of the function.
PaulS:
Your function to get the data from the barometric sensor correctly toggles the chip select pin for that sensor BUT it fails to set the other chip select pin, for the other the SPI device. It needs to set pin 10 HIGH and LOW at the appropriate times. I can never remember whether it is HIGH to activate or to deactivate. Set pin 10 HIGH at the start of the function, and LOW at the end. If that doesn't work, change which way the pin is set at the start and the end of the function.
Spot on! That is probably it!
So, I set the WiFi shield select pin to low/high, to tell it that now the barometric sensor wants to communicate, then when the barometric sensor has finished reading the data, I set the WiFi shield select pin back to the original setting? I think the penny just dropped
I've spent some time trying to debug, but not going anywhere. Setting the select pin for the barometer to HIGH (which should disable it) doesn't seem to do much.
The error code I get is that the wifi shield is not present. I'm now just playing with a simple code to see if I can get it to connect to my wifi. This is my code, same wiring as before.
#include <WiFi.h>
char ssid[] = "a?"; // your network SSID (name)
char pass[] = "b"; // your network password
int status = WL_IDLE_STATUS; // the Wifi radio's status
void setup() {
Serial.begin(9600);
// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
// don't continue:
while(true);
}
// attempt to connect to Wifi network:
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
// you're connected now, so print out the data:
Serial.print("You're connected to the network");
}
void loop() {
delay(10000);
}
Which outputs "WiFi shield not present".
Inserting the following at the beginning of the setup() method does nothing:
pinMode(9, OUTPUT); // Connected to the select pin of the barometer
digitalWrite(9, HIGH);
By unplugging pin 12 from my barometer (barometer SDO), everything works fine (except I don't get a barometer reading that is).
It turns out that this phenomenon only happens when I try to connect the barometric sensor through the CAT5 cable. When I connect it right on the breadboard next to the Arduino, all is fine.
I have no clue why this is. I have checked, rechecked, and checked again all connections. They are fine. The cable is tested and is fine. The RJ45 connectors are fine. Does simply running the signal through the CAT5 cable do something mysterious to the signal somehow?