PT100/PT1000 工业级温度传感器
来自Jack's Lab
(版本间的差异)
(→MCP3421) |
(→MCP3421) |
||
第69行: | 第69行: | ||
<source lang=cpp> | <source lang=cpp> | ||
+ | #include <Wire.h> | ||
+ | // I2C address for MCP3422 - base address for MCP3424 = 0x68 | ||
+ | #define MCP342X_ADDRESS 0X68 | ||
+ | |||
+ | // fields in configuration register | ||
+ | #define MCP342X_GAIN_FIELD 0X03 // PGA field | ||
+ | #define MCP342X_GAIN_X1 0X00 // PGA gain X1, 12 bits, 1 mV | ||
+ | #define MCP342X_GAIN_X2 0X01 // PGA gain X2, 14 bits, 250 uV | ||
+ | #define MCP342X_GAIN_X4 0X02 // PGA gain X4, 16 bits, 62.5 uV | ||
+ | #define MCP342X_GAIN_X8 0X03 // PGA gain X8, 18 bits, 15.625 uV | ||
+ | |||
+ | #define MCP342X_RES_FIELD 0X0C // resolution/rate field | ||
+ | #define MCP342X_RES_SHIFT 0X02 // shift to low bits | ||
+ | #define MCP342X_12_BIT 0X00 // 12-bit 240 SPS | ||
+ | #define MCP342X_14_BIT 0X04 // 14-bit 60 SPS | ||
+ | #define MCP342X_16_BIT 0X08 // 16-bit 15 SPS | ||
+ | #define MCP342X_18_BIT 0X0C // 18-bit 3.75 SPS | ||
+ | |||
+ | #define MCP342X_CONTINUOUS 0X10 // 1 = continuous, 0 = one-shot | ||
+ | |||
+ | #define MCP342X_CHAN_FIELD 0X60 // channel field | ||
+ | #define MCP342X_CHANNEL_1 0X00 // select MUX channel 1 | ||
+ | #define MCP342X_CHANNEL_2 0X20 // select MUX channel 2 | ||
+ | #define MCP342X_CHANNEL_3 0X40 // select MUX channel 3 | ||
+ | #define MCP342X_CHANNEL_4 0X60 // select MUX channel 4 | ||
+ | |||
+ | #define MCP342X_START 0X80 // write: start a conversion | ||
+ | #define MCP342X_BUSY 0X80 // read: output not ready | ||
+ | |||
+ | uint8_t chan = 0XFF, gain = 0XFF, res = 0XFF; | ||
+ | |||
+ | //------------------------------------------------------------------------ | ||
+ | // default adc configuration register - resolution and gain added in setup() | ||
+ | uint8_t adcConfig = MCP342X_START | MCP342X_CHANNEL_1 | MCP342X_CONTINUOUS; | ||
+ | |||
+ | // divisor to convert ADC reading to milivolts | ||
+ | uint16_t mvDivisor; | ||
+ | |||
+ | void halt(void) | ||
+ | { | ||
+ | Serial.println("Halted - check address and wiring"); | ||
+ | while(1); | ||
+ | } | ||
+ | |||
+ | // read mcp342x data - updated 10mar11/wbp | ||
+ | uint8_t mcp342xRead(int32_t &data) | ||
+ | { | ||
+ | // pointer used to form int32 data | ||
+ | uint8_t *p = (uint8_t *)&data; | ||
+ | // timeout - not really needed? | ||
+ | uint32_t start = millis(); | ||
+ | if ((adcConfig & MCP342X_RES_FIELD) == MCP342X_18_BIT) // in 18 bit mode? | ||
+ | { | ||
+ | do { // 18-bit mode | ||
+ | Wire.requestFrom(MCP342X_ADDRESS, 4); | ||
+ | if (Wire.available() != 4) { | ||
+ | Serial.println("read failed"); | ||
+ | return false; | ||
+ | } | ||
+ | for (int8_t i = 2; i >= 0; i--) { | ||
+ | p[i] = Wire.read(); | ||
+ | } | ||
+ | // extend sign bits | ||
+ | p[3] = p[2] & 0X80 ? 0XFF : 0; | ||
+ | // read config/status byte | ||
+ | uint8_t s = Wire.read(); | ||
+ | if ((s & MCP342X_BUSY) == 0) return true; // escape here | ||
+ | } while (millis() - start < 500); // allows rollover of millis() | ||
+ | } else { | ||
+ | do { // 12-bit to 16-bit mode | ||
+ | Wire.requestFrom(MCP342X_ADDRESS, 3); | ||
+ | if (Wire.available() != 3) { | ||
+ | Serial.println("read failed"); | ||
+ | return false; | ||
+ | } | ||
+ | p[1] = Wire.read(); | ||
+ | p[0] = Wire.read(); | ||
+ | // extend sign bits | ||
+ | p[2] = p[1] & 0X80 ? 0XFF : 0; | ||
+ | p[3] = p[2]; | ||
+ | // read config/status byte | ||
+ | uint8_t s = Wire.read(); | ||
+ | if ((s & MCP342X_BUSY) == 0) return true; // or escape here | ||
+ | } while (millis() - start < 500); // allows rollover of millis() | ||
+ | } | ||
+ | Serial.println("read timeout"); // dang it | ||
+ | return false; | ||
+ | } | ||
+ | |||
+ | // write mcp342x configuration byte | ||
+ | uint8_t mcp342xWrite(uint8_t config) | ||
+ | { | ||
+ | Wire.beginTransmission(MCP342X_ADDRESS); | ||
+ | Wire.write(config); | ||
+ | Wire.endTransmission(); | ||
+ | } | ||
+ | |||
+ | void setup() | ||
+ | { | ||
+ | Serial.begin(115200); | ||
+ | pinMode(D4, OUTPUT); | ||
+ | digitalWrite(D4, LOW); | ||
+ | Wire.begin(); | ||
+ | |||
+ | do { | ||
+ | Serial.println(); | ||
+ | Serial.flush(); | ||
+ | Serial.print("Enter gain (1, 2, 4, or 8): "); | ||
+ | while(Serial.available() < 1); | ||
+ | switch (Serial.read()) { | ||
+ | case '1': // ACSCII number received | ||
+ | gain = MCP342X_GAIN_X1; | ||
+ | break; | ||
+ | case '2': | ||
+ | gain = MCP342X_GAIN_X2; | ||
+ | break; | ||
+ | case '4': | ||
+ | gain = MCP342X_GAIN_X4; | ||
+ | break; | ||
+ | case '8': | ||
+ | gain = MCP342X_GAIN_X8; | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | while (gain > 3); | ||
+ | Serial.println(1 << gain, DEC); | ||
+ | |||
+ | do { | ||
+ | Serial.flush(); | ||
+ | Serial.println(); | ||
+ | Serial.print("Enter resolution (12, 14, 16, or 18): "); | ||
+ | while (Serial.available() < 2); | ||
+ | if (Serial.read() != '1') continue; | ||
+ | switch (Serial.read()) { | ||
+ | case '2': | ||
+ | res = 0; | ||
+ | break; | ||
+ | case '4': | ||
+ | res = 1; | ||
+ | break; | ||
+ | case '6': | ||
+ | res = 2; | ||
+ | break; | ||
+ | case '8': | ||
+ | res = 3; | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | while (res > 3); | ||
+ | Serial.println(12 + 2*res, DEC); | ||
+ | |||
+ | adcConfig |= res << 2 | gain | MCP342X_START; | ||
+ | |||
+ | // divisor to convert ADC reading to millivolts | ||
+ | mvDivisor = 1 << (gain + 2*res); | ||
+ | } | ||
+ | |||
+ | void loop() | ||
+ | { | ||
+ | int32_t data; | ||
+ | |||
+ | mcp342xWrite(adcConfig); | ||
+ | |||
+ | if (!mcp342xRead(data)) halt(); | ||
+ | |||
+ | // voltage in millivolts | ||
+ | double mv = (double)data/mvDivisor; | ||
+ | // uncomment line below to convert reading to microvolts | ||
+ | // int32_t uv = (data*1000L)/mvDivisor; | ||
+ | |||
+ | Serial.print("V = "); // take out the /10 below for straight mV | ||
+ | Serial.print(mv/10); // format for LM35 temperature | ||
+ | Serial.println(" mV"); | ||
+ | |||
+ | delay(2000); // 5 seconds + conversion time x 4 | ||
+ | } | ||
</source> | </source> | ||
2016年3月1日 (二) 23:16的版本
目录 |
1 概述
2 ESP8266 ADC
硬件连接:
VCC33 ---> PT1000 <-- (A0) --> 300R 1% ---> GND
void setup() { Serial.begin(115200); } void loop() { int vd = analogRead(A0); Serial.print("vd = "); Serial.println(vd); uint32_t rtd = (1024 - vd) * 300 / vd; Serial.print("rtd = "); Serial.println(rtd); delay(1000); }
3 MCP3421
- 快速测试:
#include <Wire.h> #define MCP3421_ADDRESS 0X68 void setup() { Serial.begin(115200); Wire.begin(); } void loop() { Wire.requestFrom(MCP3421_ADDRESS, 4); if (Wire.available() != 4) { Serial.println("Wire.available failed"); while(1); } int16_t v = (Wire.read() << 8); v |= Wire.read(); // read but ignore status uint8_t s = Wire.read(); //print voltage from channel one in millivolts Serial.print(v);Serial.println(" mv"); delay(1500); }
- 改进:
#include <Wire.h> // I2C address for MCP3422 - base address for MCP3424 = 0x68 #define MCP342X_ADDRESS 0X68 // fields in configuration register #define MCP342X_GAIN_FIELD 0X03 // PGA field #define MCP342X_GAIN_X1 0X00 // PGA gain X1, 12 bits, 1 mV #define MCP342X_GAIN_X2 0X01 // PGA gain X2, 14 bits, 250 uV #define MCP342X_GAIN_X4 0X02 // PGA gain X4, 16 bits, 62.5 uV #define MCP342X_GAIN_X8 0X03 // PGA gain X8, 18 bits, 15.625 uV #define MCP342X_RES_FIELD 0X0C // resolution/rate field #define MCP342X_RES_SHIFT 0X02 // shift to low bits #define MCP342X_12_BIT 0X00 // 12-bit 240 SPS #define MCP342X_14_BIT 0X04 // 14-bit 60 SPS #define MCP342X_16_BIT 0X08 // 16-bit 15 SPS #define MCP342X_18_BIT 0X0C // 18-bit 3.75 SPS #define MCP342X_CONTINUOUS 0X10 // 1 = continuous, 0 = one-shot #define MCP342X_CHAN_FIELD 0X60 // channel field #define MCP342X_CHANNEL_1 0X00 // select MUX channel 1 #define MCP342X_CHANNEL_2 0X20 // select MUX channel 2 #define MCP342X_CHANNEL_3 0X40 // select MUX channel 3 #define MCP342X_CHANNEL_4 0X60 // select MUX channel 4 #define MCP342X_START 0X80 // write: start a conversion #define MCP342X_BUSY 0X80 // read: output not ready uint8_t chan = 0XFF, gain = 0XFF, res = 0XFF; //------------------------------------------------------------------------ // default adc configuration register - resolution and gain added in setup() uint8_t adcConfig = MCP342X_START | MCP342X_CHANNEL_1 | MCP342X_CONTINUOUS; // divisor to convert ADC reading to milivolts uint16_t mvDivisor; void halt(void) { Serial.println("Halted - check address and wiring"); while(1); } // read mcp342x data - updated 10mar11/wbp uint8_t mcp342xRead(int32_t &data) { // pointer used to form int32 data uint8_t *p = (uint8_t *)&data; // timeout - not really needed? uint32_t start = millis(); if ((adcConfig & MCP342X_RES_FIELD) == MCP342X_18_BIT) // in 18 bit mode? { do { // 18-bit mode Wire.requestFrom(MCP342X_ADDRESS, 4); if (Wire.available() != 4) { Serial.println("read failed"); return false; } for (int8_t i = 2; i >= 0; i--) { p[i] = Wire.read(); } // extend sign bits p[3] = p[2] & 0X80 ? 0XFF : 0; // read config/status byte uint8_t s = Wire.read(); if ((s & MCP342X_BUSY) == 0) return true; // escape here } while (millis() - start < 500); // allows rollover of millis() } else { do { // 12-bit to 16-bit mode Wire.requestFrom(MCP342X_ADDRESS, 3); if (Wire.available() != 3) { Serial.println("read failed"); return false; } p[1] = Wire.read(); p[0] = Wire.read(); // extend sign bits p[2] = p[1] & 0X80 ? 0XFF : 0; p[3] = p[2]; // read config/status byte uint8_t s = Wire.read(); if ((s & MCP342X_BUSY) == 0) return true; // or escape here } while (millis() - start < 500); // allows rollover of millis() } Serial.println("read timeout"); // dang it return false; } // write mcp342x configuration byte uint8_t mcp342xWrite(uint8_t config) { Wire.beginTransmission(MCP342X_ADDRESS); Wire.write(config); Wire.endTransmission(); } void setup() { Serial.begin(115200); pinMode(D4, OUTPUT); digitalWrite(D4, LOW); Wire.begin(); do { Serial.println(); Serial.flush(); Serial.print("Enter gain (1, 2, 4, or 8): "); while(Serial.available() < 1); switch (Serial.read()) { case '1': // ACSCII number received gain = MCP342X_GAIN_X1; break; case '2': gain = MCP342X_GAIN_X2; break; case '4': gain = MCP342X_GAIN_X4; break; case '8': gain = MCP342X_GAIN_X8; break; } } while (gain > 3); Serial.println(1 << gain, DEC); do { Serial.flush(); Serial.println(); Serial.print("Enter resolution (12, 14, 16, or 18): "); while (Serial.available() < 2); if (Serial.read() != '1') continue; switch (Serial.read()) { case '2': res = 0; break; case '4': res = 1; break; case '6': res = 2; break; case '8': res = 3; break; } } while (res > 3); Serial.println(12 + 2*res, DEC); adcConfig |= res << 2 | gain | MCP342X_START; // divisor to convert ADC reading to millivolts mvDivisor = 1 << (gain + 2*res); } void loop() { int32_t data; mcp342xWrite(adcConfig); if (!mcp342xRead(data)) halt(); // voltage in millivolts double mv = (double)data/mvDivisor; // uncomment line below to convert reading to microvolts // int32_t uv = (data*1000L)/mvDivisor; Serial.print("V = "); // take out the /10 below for straight mV Serial.print(mv/10); // format for LM35 temperature Serial.println(" mV"); delay(2000); // 5 seconds + conversion time x 4 }
4 资源
- http://openenergymonitor.org/emon/buildingblocks/rtd-temperature-sensing
- http://forum.arduino.cc/index.php?topic=16731.0
- http://stackoverflow.com/questions/21644642/how-to-connect-pt-1000
- http://41j.com/blog/2015/01/esp8266-analogue-input/