Jeelabs Analog plug with the Apogee Pyranometer

The Jeelabs Analog Plug has the very cool MCP3424 4 channel 12-18 bit ADC. I’m going to connect it to the Apogee Pyranometer so I can can get a reading on the irradiance.

It looks like this:

Apogee SP-110

 

and has 5m cable with three leads:

  • Red: Positive from the Sensor
  • Black: Negative from the Sensor
  • Clear: GND

The pyranometer SP-110 has an output of 0.20mV per W/m2. Full sunlight is 220mV (1100 W/m2).The full range is 0-350mV or 1.75 full sun. The SP-110 is self-powered. The ADC has an internal 2.048V VREF so no need to mess with AREF.

Since full sun output is 220mV if we multiplied it by 8x we would get a range of 0-1.76V which is below VREF. The ADC has a configuration register where we can set the sample bit depth as well as the gain. Check the datasheet for all the config options.

To setup channel 1, one-shot conversion, 18-bits, x8 gain the binary would be: 10001111 or 0x8F. One-short conversion puts the ADC into standby mode. Or for the same with continuous mode it would be 0x1F.

In 18-bit sample mode, the ADC returns 4 bytes. The first 3 are data bytes, the last is the configuration. In 12,14 or 16-bit modes, the ADC returns 2 data bytes and 1 config byte.

One-shot conversion allows the ADC to go to low-power mode between conversion requests. For a 18-bit conversion, the ADC will draw ~ 36μA per conversion as < 1μA in standby (300nA). Doing 18-bit conversions continually draws about 138μA.

Using this little sketch I can get the desired output:

#include <Ports.h>
#include <RF12.h>

PortI2C p4I2C(4);
DeviceI2C adc(p4I2C, 0x68); // 0x68 address for the Analog plug with the pads unsoldered

byte Config;
int ack;

void setup() {
 ack = 0;
 // Serial
 Serial.begin(57600);
 Serial.println("\n[Bejouled MCP3424 Pyranometer]");
 ack = adc.send();
 if(ack)
     Serial.println("Got Ack");
 //adc.write(0x8F); // channel 1, 18 bit, 8x gain, one-shot conversion
 adc.stop();
}

void loop() {
 long raw;

 ack = adc.send();
 if(ack) {
   // Start new conversion
   adc.write(0x8F);

   adc.receive(); // Sets R/W bit high
   raw = (long) adc.read(0) << 16;
   raw |= (word) adc.read(0) << 8;
   raw |= adc.read(0);
   Config = adc.read(0);
   //Serial.print("Config: ");
   //Serial.println(Config,HEX);  // Configuration
   while(Config != 0x0F) {  // Loop waiting for the conversion to be finished
     Config = adc.read(0);
   }
   adc.read(1); // last poll

   adc.receive(); // Sets R/W bit high
   long data = adc.read(0);
   raw = data1 << 16;
   // check for negative values
   if(!data1) {
     raw |= (word) adc.read(0) << 8;
     raw |= adc.read(0);
   } else {
     raw = 0;
   }
   Serial.print("  Raw: ");
   Serial.print(raw);
   adc.read(1);
   adc.stop();

   long ir = (raw/8)*5; // Remove the 8x gain and multiply by 5W/m2 per mV
   Serial.print(" Irradiance: ");
   Serial.print(ir);
   Serial.println("W/m2");
 }
}