Для измерения термисторов решил сделать омметр, но не устраивает точность измерений. Измерять нужно от 1кОм до 60 кОм, одновременно от 12 до 30 термисторов . Делитель поставил на 70,9 кОм.( делитель стоит между А0-GND для 1 мультиплексора и А1-GND для 2 мультиплексора) Для увеличения точности думаю или вводить поправочные коэффициенты, вычесленные эмперическим путем, либо попробовать собрать схему с мостом Уинстона, но с ним уменя как раз проблема - никак не могу сообразить как это сделать на основе ардуино. Схема прилагаю: Код (C++): #define EN 3 #define S0 4 #define S1 5 #define S2 6 #define S3 7 #define SIG1 A0 #define SIG2 A1 #define R1 70900 #define U_THERMISTOR 5000 //Напряжение подаваемое на термистор в мВольтах void setup() { Serial.begin(9600); pinMode(S0, OUTPUT); pinMode(S1, OUTPUT); pinMode(S2, OUTPUT); pinMode(S3, OUTPUT); digitalWrite(S0, LOW); digitalWrite(S1, LOW); digitalWrite(S2, LOW); digitalWrite(S3, LOW); pinMode(EN, OUTPUT); digitalWrite(EN, LOW); delay(1000); //Ждем переходные процессы в схеме } int ADCMux; void loop() { //Loop through and read all 16 values //Reports back Value at channel 6 is: 346 for (int j = 0; j < 2; j ++) { Serial.print("Mux: "); Serial.print(j + 1); for (int i = 0; i < 16; i ++) { Serial.print(" ch"); Serial.print(i); Serial.print(": "); ADCMux = readMux(j + 1, i); Serial.print(" [v1: "); Serial.print(ConvertADCToVoltage(ADCMux)); //Serial.print(ADCMux); Serial.print(" r2: "); Serial.print(CalculateThermistor(ConvertADCToVoltage(ADCMux))); Serial.print("]"); } Serial.println(); } Serial.println(); delay(2000); } /** Функция выбора мультиплексора и канала в нём @param mux_n Номер мультиплексора 1-2 @param channel Канал 0-15 @return Значение АЦП, -1 - ошибка выбора мультиплексора */ int readMux(int mux_n, int channel) { int adc = 0; if ((mux_n <= 0) || (mux_n >= 3)) return -1; int controlPin[] = {S0, S1, S2, S3}; int muxChannel[16][4] = { {0, 0, 0, 0}, //channel 0 {1, 0, 0, 0}, //channel 1 {0, 1, 0, 0}, //channel 2 {1, 1, 0, 0}, //channel 3 {0, 0, 1, 0}, //channel 4 {1, 0, 1, 0}, //channel 5 {0, 1, 1, 0}, //channel 6 {1, 1, 1, 0}, //channel 7 {0, 0, 0, 1}, //channel 8 {1, 0, 0, 1}, //channel 9 {0, 1, 0, 1}, //channel 10 {1, 1, 0, 1}, //channel 11 {0, 0, 1, 1}, //channel 12 {1, 0, 1, 1}, //channel 13 {0, 1, 1, 1}, //channel 14 {1, 1, 1, 1} //channel 15 }; //loop through the 4 sig for (int i = 0; i < 4; i ++) { digitalWrite(controlPin[i], muxChannel[channel][i]); } delay(200); //return the value for (int i = 0; i < 16; i++) adc += analogRead(mux_n == 1 ? SIG1 : SIG2); return adc / 16; //return analogRead(mux_n == 1 ? SIG1 : SIG2); } /** Конвертируем показания АЦП в напряжение, в мВольтах @param adc показания АЦП @return напряжение, в мВольтах */ uint16_t ConvertADCToVoltage(uint16_t adc) { return (adc * 4.8828125); //adc * (5000mV / 1024) } /** Находим значение термистора, в Ом @param v1 напряжение на делителе @return сопротивление термистора, в Ом */ uint32_t CalculateThermistor(uint16_t v1) { return ((U_THERMISTOR * R1) / v1) - R1; }
Такие штуки делают на основе RC измерителя. Но нужен очень стабильный опорник и конденсатор с нулевым ТКЕ.
Начните с конца. Какая точность вам нужна? Пересчитайте по схемам в напряжение, а далее нужно думать что получится
Звер не так. Если бы так то постоянно меняли свои точные показания. В весах какраз точность загрублена. А тут ты взял его в руки—сопротивление поплыло. Открыл форточку— поплыло. Это если точно. Если грубо— можно омметром.
ТС на ардуино.ру пишет, что измерение проводится в термостате с точностью 0.03 градуса (если я правильно понял) Но вообще он какой-то мутный (ТС а не термостат - не ясно, понимает ли он то, что делает...
Опять же встает вопрос—насколько точен сам термистор?И вопрос 2— калибровка точки отсчета( ноля например или+100 С). Сам по себе термистор— аналоговый прибор. Поэтому я и удивился.
Вам целочисленная арифметика портит всю точность. Код (C++): return (adc * 4.8828125) Это на самом деле работает так: Код (C++): return (adc * 4) Поменяйте тип ConvertADCToVoltage() на float или double.