Проблема с АЦП на Леонардо

AndryGladky
Offline
Зарегистрирован: 09.10.2014

Здравствуйте, помогите разобратся в проблеме считывания АЦП. Хочу считать напряжение с резестивного делителя, и выводить кубики на дисплей WH1602, но до 10 процентов и 4 кубиков все работает нормально, изменяется, а дальше почему то нет. Хотя в мониторе последовательного порта, изменения аналогово входа изменяются нормально. Не могу понять в чем причина. Код прилагаю.

 /*  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 */

#include <LiquidCrystal.h>

// пины индикатора
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// присваеваем целочисловое значение на
// аналоговый пин и переменную для хранения значения
int val = 0;
int gbo = 3;

void setup() {
  // размер екрана
  lcd.begin(16, 2);
    // установка контрасности дисплея на 9 пине
  Serial.begin(9600);  //  установка связи по serial
  analogWrite (9, 300);
  }

void loop() {
  lcd.clear();
  // выводим слова уровень газа
  lcd.setCursor(0, 0);
  lcd.print("\xA9""po""\xB3""e""\xBD\xC4""\x20""\xB4""a""\xB7""a");
  Serial.println(val);  // выводим полученное значение в порт

  val = analogRead(gbo)>>2; // считываем значение с аналогового порта 

  if (val < 80) // 5 процентов бака
  {lcd.setCursor(14, 0); // выводим проценты
   lcd.print("5%");
   lcd.setCursor(0, 1); //выводим два кубика на нижней строке
   lcd.print("\xFF\xFF");}
   
   if (80 > val < 100) //10 процентов бака
   {lcd.setCursor(13, 0);// выводим проценты
   lcd.print("10%");
   lcd.setCursor(0, 1);//выводим 4 кубика на нижней строке
   lcd.print("\xFF\xFF\xFF\xFF");}
   
   if (100 > val < 110)   //20 процентов бака
   {lcd.setCursor(13, 0);// выводим проценты
   lcd.print("20%");
   lcd.setCursor(0, 1);//выводим 6 кубиков на нижней строке
   lcd.print("\xFF\xFF\xFF\xFF\xFF\xFF");}
  
   if (110 > val < 120)   //30 процентов бака
   {lcd.setCursor(13, 0);// выводим проценты
   lcd.print("30%");
   lcd.setCursor(0, 1);//выводим 8 кубиков на нижней строке
   lcd.print("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF");}
   
   if (val > 170)
   {lcd.setCursor(12, 0);
    lcd.print("100%");
    lcd.setCursor(15, 1);
    lcd.print("\xFF");
    lcd.setCursor(14, 1);
    lcd.print("\xFF");
    lcd.setCursor(13, 1);
    lcd.print("\xFF");}
    delay(500);
    lcd.clear();
 }

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

AndryGladky, что это за вольные конструкции у оператора  if (xx > y < zz)   ??

AndryGladky
Offline
Зарегистрирован: 09.10.2014

Как правильно тогда задать рамки АЦП при которых будет выполнятся код?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013
arduinec
Offline
Зарегистрирован: 01.09.2015

AndryGladky пишет:

Как правильно тогда задать рамки АЦП при которых будет выполнятся код?

if ((xx < y) && (y < zz))

AndryGladky
Offline
Зарегистрирован: 09.10.2014

Переписал код теперь показывает только 5 процентов. При дальнейшем изменении АЦП, исчезает проценты и кубики.

  
  
 /*  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 */

#include <LiquidCrystal.h>

// пины индикатора
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// присваеваем целочисловое значение на
// аналоговый пин и переменную для хранения значения
int val = 0;
int gbo = 3;

void setup() {
  // размер екрана
  lcd.begin(16, 2);
    // установка контрасности дисплея на 9 пине
  Serial.begin(9600);  //  установка связи по serial
  analogWrite (9, 300);
  }

void loop() {

  // выводим слова уровень газа
  lcd.setCursor(0, 0);
  lcd.print("\xA9""po""\xB3""e""\xBD\xC4""\x20""\xB4""a""\xB7""a");
  Serial.println(val);  // выводим полученное значение в порт

  val = analogRead(gbo)>>2; // считываем значение с аналогового порта 

   if (val < 80) // 5 процентов бака
   {lcd.setCursor(14, 0); // выводим проценты
   lcd.print("5%");
   lcd.setCursor(0, 1); //выводим два кубика на нижней строке
   lcd.print("\xFF\xFF");}
   
   if ((val >= 100) && (val <= 80)) //10 процентов бака
   {lcd.setCursor(13, 0);// выводим проценты
   lcd.print("10%");
   lcd.setCursor(0, 1);//выводим 4 кубика на нижней строке
   lcd.print("\xFF\xFF\xFF\xFF");}
   
   if ((val >= 110) && (val <= 100))   //20 процентов бака
   {lcd.setCursor(13, 0);// выводим проценты
   lcd.print("20%");
   lcd.setCursor(0, 1);//выводим 6 кубиков на нижней строке
   lcd.print("\xFF\xFF\xFF\xFF\xFF\xFF");}
  
   if ((val >= 120) && (val <= 110))   //30 процентов бака
   {lcd.setCursor(13, 0);// выводим проценты
   lcd.print("30%");
   lcd.setCursor(0, 1);//выводим 8 кубиков на нижней строке
   lcd.print("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF");}
   
   if (val > 170)
   {lcd.setCursor(12, 0);
    lcd.print("100%");
    lcd.setCursor(0, 1);
    lcd.print("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF");    }
    delay (500);
    lcd.clear ();
 }
arduinec
Offline
Зарегистрирован: 01.09.2015

if ((val >= 100) && (val <= 80)) - никогда не выполниться

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

AndryGladky, я б вобще всё упростил, с аналог реад можно скинуть 6 бит, и будет результат 0..15, как раз для рисования прямоугольников. Как-то так:

void loop() {

// выводим слова уровень газа
lcd.setCursor(0, 0);
lcd.print("\xA9""po""\xB3""e""\xBD\xC4""\x20""\xB4""a""\xB7""a");
Serial.println(val);  // выводим полученное значение в порт
val = analogRead(gbo)>>6; // считываем значение с аналогового порта 
lcd.setCursor(0, 1);
for (byte n=val+1; n--; n==0){  lcd.write('\xFF'); } //прямоугольники
for (byte n=16-val; n--; n==0){  lcd.write(' '); } //пустышки
lcd.setCursor(13, 0);// выводим проценты
float proc=val*6.6666;
lcd.print(proc,0);
lcd.write('%');
}

 

AndryGladky
Offline
Зарегистрирован: 09.10.2014

Как тогда здать правильно рамки для ацп?

Duino A.R.
Offline
Зарегистрирован: 25.05.2015

arduinec пишет:

if ((val >= 100) && (val <= 80)) - никогда не выполниться

Да. Так было и в первом варианте программы, и в модифицированном.

Кроме этого, при переходе от одного "IF" к другому сохраняется общая граница "меньше (больше) или равно". Если в одной проверке Вы проверяете условие, включая границу, то при проверке альтернативного условия эту границу следует исключить строгим "меньше (больше)".

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Можно не парить МК и сравнение сделать проще, например, так:

if (val < 80) {
  ...
}
else if (val < 100) {
  ...
}
else if (val < 110) {
   ...
}
else {
  ...
}

При такой реализации выполняется всегда только одна ветка if, поэтому срвнивать границы не нужно, достаточно сравнивать только верхнюю границу. Разумеется сравнивать нужно с самого маленького граничного значения и в каждом следующем, граница должна быть выше (в примере это 80, 100, 110, т.е. по возрастанию). Т.о. в первый if попадет всё, что меньше 80, во второй от 80 и меньше 100, в третий от 100 и меньше 110, в четвертый от 110 и выше.

 

 

AndryGladky
Offline
Зарегистрирован: 09.10.2014

Поставил по методу kisoft, работает нормально. За упрощенный вариант тоже спасибо, попробую разобратся и в нем. Вот код, может кому пригодится.


/*  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 */

#include <LiquidCrystal.h>

// пины индикатора
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// присваеваем целочисловое значение на
// аналоговый пин и переменную для хранения значения
int val = 0;
int gbo = 3;

void setup() {
  // размер екрана
  lcd.begin(16, 2);
    // установка контрасности дисплея на 9 пине
  Serial.begin(9600);  //  установка связи по serial
  analogWrite (9, 300);
  }

void loop() {

  // выводим слова уровень газа
  lcd.setCursor(0, 0);
  lcd.print("\xA9""po""\xB3""e""\xBD\xC4""\x20""\xB4""a""\xB7""a");
  Serial.println(val);  // выводим полученное значение в порт

  val = analogRead(gbo)>>2; // считываем значение с аналогового порта 

   if (val < 80) // 5 процентов бака
   {lcd.setCursor(13, 0); // выводим проценты
   lcd.print("\x20""5%");
   lcd.setCursor(0, 1); //выводим 1 кубик на нижней строке
   lcd.print("\xFF\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20");}
   
   else if (val < 100) //10 процентов бака
   {lcd.setCursor(13, 0);// выводим проценты
   lcd.print("10%");
   lcd.setCursor(0, 1);//выводим 3 кубика на нижней строке
   lcd.print("\xFF\xFF\xFF\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20");}
   
   else if (val < 110)   //20 процентов бака
   {lcd.setCursor(13, 0);// выводим проценты
   lcd.print("20%");
   lcd.setCursor(0, 1);//выводим 5 кубиков на нижней строке
   lcd.print("\xFF\xFF\xFF\xFF\xFF\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20");}
  
   else if (val < 120)   //30 процентов бака
   {lcd.setCursor(13, 0);// выводим проценты
   lcd.print("30%");
   lcd.setCursor(0, 1);//выводим 7 кубиков на нижней строке
   lcd.print("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x20\x20\x20\x20\x20\x20\x20\x20\x20");}
   
   else if (val < 130)   //40 процентов бака
   {lcd.setCursor(13, 0);// выводим проценты
   lcd.print("40%");
   lcd.setCursor(0, 1);//выводим 9 кубиков на нижней строке
   lcd.print("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x20\x20\x20\x20\x20\x20\x20");}
   
   else if (val < 150)   //50 процентов бака
   {lcd.setCursor(13, 0);// выводим проценты
   lcd.print("50%");
   lcd.setCursor(0, 1);//выводим 11 кубиков на нижней строке
   lcd.print("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x20\x20\x20\x20\x20");}
   
   else if (val < 160)   //60 процентов бака
   {lcd.setCursor(13, 0);// выводим проценты
   lcd.print("60%");
   lcd.setCursor(0, 1);//выводим 13 кубиков на нижней строке
   lcd.print("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x20\x20\x20");}
   
   else if (val < 170)   //70 процентов бака
   {lcd.setCursor(13, 0);// выводим проценты
   lcd.print("70%");
   lcd.setCursor(0, 1);//выводим 15 кубиков на нижней строке
   lcd.print("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x20");}
   
   else if (val < 225)  //80 процентов бака
   {lcd.setCursor(13, 0);// выводим проценты
   lcd.print("80%");
   lcd.setCursor(0, 1);//выводим 16 кубиков на нижней строке
   lcd.print("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF");}
   delay (1000);
    
 }
dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

AndryGladky, по последнему вашему скетчу -между значениями 170 и 175 у вас "чёрная дыра". И командой lcd.clear лучше не злоупотреблять, по крайней мере не запускать её на каждом круге loop. Она очень медленно выполняется, в результате человек видит как изображение моргает. Рисуйте лучше все 16 символов, прямоугольники + пробелы.

AndryGladky
Offline
Зарегистрирован: 09.10.2014

Да дыру я увидел потом убрал, а за символы спасибо, так стало значительно лучше.

AndryGladky
Offline
Зарегистрирован: 09.10.2014

Что бы не создавать сотню тем спрошу тут. Можно ли регулировать подсветку дисплея 16х2 через шим.

И как правильно подключить ее для регулировки.

 

Клапауций 070
Offline
Зарегистрирован: 26.09.2015

AndryGladky пишет:

Что бы не создавать сотню тем спрошу тут. Можно ли регулировать подсветку дисплея 16х2 через шим.

И как правильно подключить ее для регулировки.

http://arduino.ru/forum/programmirovanie/lcd-upravlenie-podsvetkoi