Проблема с АЦП Атмега8

AnFo
Offline
Зарегистрирован: 02.11.2018

Пишу таймер, для установки значений использую потенциометры. При переходе с протеуса на ардуино иде с атмегой8 (8 МГц) появилась проблема с АЦП. Максимальные значения получаются при напряжении 1.1В на входе АЦП. Причём изменяя внутренний источник опорного, результат остаётся тот же. На фото с протеуса видно, что при напряжении с потенциометра 0,85В значение на первом индикаторе 92, что есть практически максимальным. С чем это связано? Может есть недоработки в исходниках программы ардуины? Значения читаются обычной командой analogRead() и через map() преобразуются в значения для индикаторов.

b707
Offline
Зарегистрирован: 26.05.2017

выложите скетч, непонятно что значит "изменяя внутренний источник опорного" ?

Внутренний источник опорного напряжения вы изменить не можете, он всегда 1.1в Можно использовать внешнее опорное, например напряжение питания - тогда можно будет мерить значения от 0в до VCC

AnFo
Offline
Зарегистрирован: 02.11.2018

Согласен, ошибся. Изменяя источник опорного. Времени довести до ума скетч не было, поэтому извините, если что-то не понятно)

#include <TimerOne.h>

const byte digit_pins[5] = {6,5,4,8,7};
const byte data_pin = 12;
const byte sh_pin = 13;
const byte st_pin = 11;
const byte interruptPin = 2;
const byte X = 2;

int temp1;

const byte load = 10;

const byte minV = 20;
const byte maxV = 950;

unsigned short int sec = 0;
unsigned short int santsec = 0;
unsigned short int power = 0;

boolean check = false;
boolean longPressed = false;
boolean buttonCheck = false;
unsigned long period;

unsigned long pause;

byte digit = 0;
unsigned int counter = 0;


void setup() {

    pinMode(load, OUTPUT);      //Оптосимистор
    digitalWrite(load, LOW);      //____________________
    for(int i=0; i<5; i++){     //Инициализация--------------------------------------------------------
        pinMode(digit_pins[i], OUTPUT);   //-------------
    digitalWrite(digit_pins[i], LOW); //Разряды
    }           //__________________
    pinMode(data_pin, OUTPUT);      //-------------------
    pinMode(sh_pin, OUTPUT);      // Сдвиговый регистр
    pinMode(st_pin, OUTPUT);      //___________________
    pinMode(A2, INPUT);       // Потенциометр 3
    digitalWrite(A2, LOW);      //___________________

    pinMode(A0, INPUT);       // Потенциометр 1
    digitalWrite(A2, LOW);
    pinMode(A1, INPUT);       // Потенциометр 2
    digitalWrite(A1, LOW);
    pinMode(A3, INPUT);       // Кнопка
    digitalWrite(A3, LOW);
    pinMode(interruptPin, INPUT);       // Синус
    digitalWrite(interruptPin, LOW);
}

void loop() {

  while(1){
   sec = map(((constrain(analogRead(A0),minV,maxV))), minV, maxV, 0, 9);
  
   santsec = map(((constrain(analogRead(A1),minV,maxV))/10)*10, minV, maxV, 1, 99);

   power = map(((constrain(analogRead(A2),minV,maxV))/10)*10,minV , maxV, 15, 99);
   int temp = map(power, 15, 99, 2000, 10000);
   update();
   if ((check == 0) && (longPressed == 0) ) {
      if (digitalRead(A3)) {
   temp1 = (10000 - temp)/X;

   longPressed = true;
   period =(sec*100 + santsec);
   check = true;
   attachInterrupt(0,resumeTimer, LOW);
   }
   }
   if ((buttonCheck == 1)&&(digitalRead(A3)==0)){
    buttonCheck = 0;
    Timer1.initialize(500000/X);
    Timer1.attachInterrupt(button);
   }
   }
  }

 

b707
Offline
Зарегистрирован: 26.05.2017

строка 15 просто песня - как вы думаете, какое у вас значение в переменной maxV ?

В итоге вы сами приводите значения к неправильном диапазону.

AnFo
Offline
Зарегистрирован: 02.11.2018

maxV и minV были введены опытным путём для огранечения масимальных и минимальных значений в виду использования некачественных резисторов. Функция constrain() не даёт значениям АЦП вылазить за эти пределы, так как тогда из-за проволочных резисторов нельзя достичь максимального значения. Так максимальное значение будет достигаться от 950 до 1023 значений АЦП

b707
Offline
Зарегистрирован: 26.05.2017

AnFo - из кода вашего сразу возникло подозрение, что вы в программировании мало понимаете. А теперь это 100% уверенность. ВНИМАТЕЛЬНО посмотрите на строку 15. Все еще не видите грубую (ГРУБЕЙШУЮ) ошибку?

AnFo
Offline
Зарегистрирован: 02.11.2018

Спасибо огромное!! В программировании разбираюсь, в старом скетче стоял тип unsigned int, видимо ошибся, когда переносил из протеуса в IDE. Даже немного стыдно. Я думал вы намикаете на значение, а не тип данных, которому это значение присваивается, пэтому и 100% уверенность. И да, это мой первый проект на ардуино, некоторыми функциями пытаюсь переходить на С, в будущем хочу программировать именно на С. Если есть весомые замечания, то говорите, не стесняйтесь. Сам хочу немного ускорить рабту программы, так как во время работы таймера и прерываний немного мерцают индикаторы.

b707
Offline
Зарегистрирован: 26.05.2017

AnFo - при таком maxV максимальное значение с АЦП у вас должно быть 182. Похоже на то, что вы видите в Протеусе? - по-моему да

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

AnFo пишет:

в виду использования некачественных резисторов

А, так это резисторы виноваты. Понятно.