Since I'm using a 2.7v arduino (the MKRZERO), the level converter isn't necessary.
I've included the code, below, though it isn't relevant since the sensor doesn't care what's going on on the processor. The clock, MISO, MOSI channels, and as you can see in the .jpg from the original post, are being driven exactly as diagrammed in the datasheet, but the sensor isn't responding. It's in an extremely experimental state, but it's driving the comms pins exactly as required (see the .jpg), so again - it's irrelevant.
The wiring diagram is, as stated in the original post, exactly as specified in the datasheet. Since I'm not using the arduino SPI library, I could be using any pins, but for the sake of self-documentation I used SCK, MOSI, and MISO. On the MKRZERO, they are 9, 8, and 10, respectively. SCLK, SDO, and SDI are pins 8, 6, and 7 on the ms5611. I've included the 100nF capacitor between V+ and GND, right at the MS5611, and as mentioned in the original post, the protocol select and chip select are permanently grounded.
I've double-checked that the datasheet is referring to "out" and "in" from the MS5611's perspective. In other words, SDO is data leaving the MS5611. (I'd hoped that my mistake had been that "out" was data out from the arduino and "in" was data entering the arduino.)
Operating on the assumption that I might have overheated the sensors while soldering them, or that I might have had a bad batch, I ordered another set from a different distributor and I have exactly the same problem. The datasheet limits soldering time/temp to 40s @ 250C. I soldered @ 250C for about 32 seconds, total, in 4s bursts... allowing the chip to cool fully between soldering each pin. I was very careful not to contaminate the vent holes with solder or flux.
#include <SPI.h>
// ASSUMES THAT SCK IS LOW TO BEGIN WITH.
void bit_out(int bit) {
digitalWrite(MOSI, bit?HIGH:LOW);
delayMicroseconds(50);
digitalWrite(SCK, HIGH);
delayMicroseconds(50);
digitalWrite(SCK, LOW);
}
int bit_in() {
int bit;
digitalWrite(SCK, HIGH);
delayMicroseconds(50);
bit = digitalRead(MISO);
digitalWrite(SCK, LOW);
delayMicroseconds(50);
return bit;
}
// SPI Mode 0. Most Significant Bit (MSB) first. Output on falling edge, capture on rising.
// I'm not using the arduino's built-in SPI library for a couple reasons;
// * The SPI lib assumes that you are receiving 8 bits for every 8 bits sent or 16 for 16.
// This is simply not true for the ms5611. I'm not entirely sure on this, but the other
// issues are sufficient for me to write my own comms.
// * I could possibly work around the bad 8/16 arduino lib assumption, but it would mean
// having SCK/SCLK oscillating while conversions are being done, which causes conversion
// noise.
// * Having 2 ms5611s on the same arduino means having them on separate busses (if I want
// to be talking to one while the other is converting). This is, again, because I don't want
// to be running the bus clock while a sensor is converting. I'll eventually require at least 2
// ms5611s per arduino, so the SPI library is not an option.
long int spi_command(byte command, unsigned int wait_time, int result_len) {
digitalWrite(SCK, LOW);
for(int i=0; i<8; i++) {
bit_out(((0x80>>i)&command)?HIGH:LOW);
}
digitalWrite(MOSI, LOW);
delayMicroseconds(wait_time);
long int result = 0;
for(int i=0; i<result_len; i++) {
result <<= 1;
result |= bit_in();
}
return result;
}
void ms5611_reset() {
spi_command(0x1e, 0, 0);
// The required delay time is 2.8ms, but I've had issues w/ badly clocked arduinos, so
// I'm giving myself some padding.
delayMicroseconds(3500);
}
//OSR = 4096 for best resolution
unsigned long ms5611_temp() {
spi_command(0x48, 9000, 0);
return spi_command(0x00, 0, 24);
}
//OSR = 4096 for best resolution
unsigned long ms5611_pressure() {
spi_command(0x58, 9000, 0);
return spi_command(0x00, 0, 24);
}
void setup() {
// put your setup code here, to run once:
Serial.begin(19200);
delay(3000);
Serial.println("starting");
Serial.println(HIGH);
Serial.println(LOW);
pinMode(SCK, OUTPUT);
digitalWrite(SCK, LOW);
pinMode(MOSI, OUTPUT);
digitalWrite(MOSI, LOW);
pinMode(MISO, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
ms5611_reset();
}
void loop() {
//ms5611_reset();
//delay(10);
// put your main code here, to run repeatedly:
int index = 0;
for(byte c=0xa0; c<=0xa0; c++) {
Serial.println(spi_command(c, 500, 24));
delay (300);
}
}