//This operates with a DIY breakout using two MCP3201 12 bit ADCs. //Uno pin8 to ADC1 pin5 CS //Uno pin9 to ADC2 pin5 CS //Uno pin12 to ADC pin6 Dout (Both ADC's) //Uno pin13 to ADC pin7 SCK (Both ADC's) //Sketch gets the raw ADC values from ADC1, followed immediately by ADC2 based on sketch by SpeedLimit88. //Hard coded offsets (zeroref) applied to both channels. //running average routine returns average of ADC2 only. //running max peak and min peak values of ADC2 only. //Breakout board designed for volt sample delivering around 1V peak to ADC1, //and current sample from ACS712 chip to ADC2. Slightly differing pre-ADC circuitry. //ADC ref = 4.096V precision,(0.1%) and output range is 0-4096, so returned values equal millivolts. #include #include const int CSPinADC1 = 8; const int CSPinADC2 = 9; unsigned int rawADC1 = 0; unsigned int rawADC2 = 0; byte inByte = 0; byte monPort = 4; int instADC1; int instADC2; const int zeroref1 = 2566; const int zeroref2 = 2565; //------------- for the smoothing routine -------------------------- const int numReadings = 40; int readings[numReadings]; // the readings from the ADC int readIndex = 0; // the index of the current reading long total = 0; // the running total long averageADC2 = 0; // the average // -------------- for the max/min routine -------------------------- elapsedMillis timer0; #define interval 305 int maxADC2; int minADC2 = 0; void setup() { Serial.begin(115200); //Serial.println("Dual MCP3201 test"); SPI.begin(); SPI.setBitOrder(MSBFIRST); SPI.setClockDivider(SPI_CLOCK_DIV8); pinMode(CSPinADC1, OUTPUT); digitalWrite(CSPinADC1, HIGH); pinMode(CSPinADC2, OUTPUT); digitalWrite(CSPinADC2, HIGH); pinMode(monPort, OUTPUT); // for averaging routine, initialize all the readings to 0: for (int thisReading = 0; thisReading < numReadings; thisReading++) { readings[thisReading] = 0; } timer0 = 0; // clear the timer at the end of startup } void loop() { digitalWrite (monPort, LOW);//temporary to measure read time with oscilloscope GetADC1(); GetADC2(); digitalWrite (monPort, HIGH); //------------- get max/min values from ADC2 ---------------- constrain(maxADC2, 0, 2048); constrain(minADC2, -2048, 0); int prevmaxADC2 = maxADC2; int prevminADC2 = minADC2; if (timer0 < interval) { maxADC2 = max(prevmaxADC2, instADC2); minADC2 = min(instADC2, prevminADC2); } if (timer0 > interval) { maxADC2 = max(9 * maxADC2 / 10, abs(instADC2));//slow decay of max minADC2 = min(9 * minADC2 / 10, instADC2);//slow decay of min timer0 -= interval; //reset the timer } // ------------end of max/min -------------------------- avgADC2(); Serial.print(instADC1); Serial.print(", "); Serial.print(instADC2); Serial.print(", "); Serial.print(averageADC2); Serial.print(", "); Serial.print(maxADC2); Serial.print(", "); Serial.println(minADC2); } unsigned int GetADC1() { //------- reads a sample from ADC1 --- digitalWrite(CSPinADC1, LOW); rawADC1 = SPI.transfer(0x00); rawADC1 = rawADC1 << 8; inByte = SPI.transfer(0x00); rawADC1 = rawADC1 | inByte; digitalWrite(CSPinADC1, HIGH); rawADC1 = rawADC1 >> 1; rawADC1 = rawADC1 & 0b0000111111111111; instADC1 = rawADC1 - zeroref1; return instADC1; } //----------- reads a sample from ADC2 --- unsigned int GetADC2() { digitalWrite(CSPinADC2, LOW); rawADC2 = SPI.transfer(0x00); rawADC2 = rawADC2 << 8; inByte = SPI.transfer(0x00); rawADC2 = rawADC2 | inByte; digitalWrite(CSPinADC2, HIGH); rawADC2 = rawADC2 >> 1; rawADC2 = rawADC2 & 0b0000111111111111; instADC2 = rawADC2 - zeroref2; return instADC2; } //------------Running Average routine ---- int avgADC2() { // subtract the last reading: total = total - readings[readIndex]; // read from the sensor: readings[readIndex] = instADC2; // add the reading to the total: total = total + readings[readIndex]; // advance to the next position in the array: readIndex = readIndex + 1; // if we're at the end of the array... if (readIndex >= numReadings) { // ...wrap around to the beginning: readIndex = 0; } // calculate the average: averageADC2 = total / numReadings; return averageADC2; }