Форум программистов, компьютерный форум, киберфорум
Arduino
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/40: Рейтинг темы: голосов - 40, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 03.10.2015
Сообщений: 25
1

СкачкИ показаний на дисплее

16.09.2019, 19:14. Показов 8245. Ответов 31

Author24 — интернет-сервис помощи студентам
Доброго времени суток!
Подходящей темы в разделе не нашел, поэтому создал новую. Если модераторы знают о существовании подходящей темы, то переместите пожалуйста мой вопрос туда.
Только начал изучать Arduino, создаю скетч за скетчем, прогоняю в Uno и т.д..
В одном из скетчей по работе с дисплеем Nokia5110, измеряющего температуру, решил добавить потенциометр и поиграться... и столкнулся с интересной проблемкой.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <PCD8544.h>   // ..\libraries\pcd8544-master\
 
float temp = 0;                  // переменная с плавающей точкой
static PCD8544 lcd;              // даем имя подключенному дисплею (lcd)
static const byte Lm35Pin = 14;  // аналоговый пин (A0), к которому подключен LM35
byte PotPin = A2;                // аналоговый пин (A2) подключения потенциометра (16)
word PotVal = 0;                 // переменная для хранения значений потенциометра
 
void setup() {   // функция инициализации и старта
  lcd.begin(84, 48);          // инициализируем дисплей
  analogReference(INTERNAL);  // подключаем внутренний ИОН на 1.1V
}
 
void loop() {   // функция основной программы
  // подсчитываем температуру (в Цельсиях)...
  temp = ReadSens(Lm35Pin);         // снимем данные с пина Lm35Pin [время работы функции: 116...120 мкс]
  temp = (temp * 109.99) / 1024.0;  // [время вычисления: 24 мкс]
  myDisplay(0, 0, 1, "`C", temp);   // отправляем данные на дисплей [время работы функции: 16...18 мс]
  temp = ReadSens(PotPin);          // снимем данные с пина потенциометра
  PotVal = map(temp, 0, 1023, 0, 100);   // сузим границы полученных значений до 0...100
  myDisplay(0, 8, 0, "%", PotVal);  // отправляем данные на дисплей
  delay(500);                       // ждем 500 мсек
}
 
void myDisplay(byte x, byte y, char z, char str[], float temp) {   // функция вывода данных на дисплей
  lcd.setCursor(x, y); // начиная с (X,Y)...
  lcd.clearLine();     // очистим строку, соответствующую ординате Y
  lcd.print(temp, z);  // выводим TEMP, с точностью Z после запятой
  lcd.print(str);      // выводим писанину
}
 
int ReadSens(char pin) {  // функция чтения данных с аналогового входа
  temp = 0;
  temp = analogRead(pin); // снимем данные с аналогового входа
  return temp;            // вернем результат отправителю
}
Если в коде удалить/закоментировать все связанное с каким-то одним измерением - температуры или потенциометра - то оставшаяся часть прекрасно работает.
В скетче "ТОЛЬКО для потенциомера" показания идут плавно и линейно, в оба направления: 0%...88% (если "+" снимать с пина Vin [4.4V]). И совершенно не зависит от скорости вращения ручки. Потенциометр линейный.
В вышеуказанном скетче уже на 30 градусах поворота показывает 100%. Дальнейший поворот ничего для показаний потенциометра не меняет - все те же 100%. Это раз!
Второе... Когда показания (по дисплею) доходят где-то до 60...80%, появляются отклонения в десятых долях температуры (+-0.3). Не просто отклонения в какую-то одну сторону, а именно скачкИ вверх-вниз. К 100% отклонения увеличиваются. После 100%, если продолжаю вращать ручку переменника, отклонения появляются сначала на единицах, а потом и на десятках градусов. И эти скачкИ продолжаются, пока не выведу потенциометр в ноль, или не спущу ниже 60%.
Сначала грешил на близость аналоговых входов и какие-то фантомные помехи :-). Смена аналогового пина ситуацию не меняет. Запитка потенциометра от внешних 5V тоже ничего не меняет (ну, кроме процентов; это логично).
Изменение времени задержки цикла loop() тоже не помогает.
Чего в скетче не хватает? Где конфликт?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.09.2019, 19:14
Ответы с готовыми решениями:

Дистанционное снятие показаний с электросчетчика КАСКАД-1-МТ с дальнейшей передачей показаний в Home Assistant по BLE
Добрый день. Готового устройства пока нет. Но на макетке все работает. Проблема была получить...

Разность показаний на дисплее
Уважаемые форумчане, помогите решить вопрос с выводом разности показаний на дисплей. В программе...

Найти в заданной серии показаний прибора минимальное произведение двух показаний
Решение: program C4_DEMO2015B; const C = 10000000; var nums : array of real; min_pr :...

Найти минимальное произведение двух показаний из множества показаний прибора
Здравствуйте. Я попытался решить самую последнюю задачу C3 из ЕГЭ по информатике. Но моя программа...

Найти в заданной серии показаний датчика минимальное чётное произведение двух показаний (из егэ)
Датчик передаёт каждую секунду по каналу связи неотрицательное целое число, не превосходящее 1000...

31
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
16.09.2019, 19:51 2
Что за потенциометр и как его подключали?

C++
1
2
3
4
5
int ReadSens(char pin) {  // функция чтения данных с аналогового входа
  temp = 0;
  temp = analogRead(pin); // снимем данные с аналогового входа
  return temp;            // вернем результат отправителю
}
Что за индусокод?

C++
1
2
3
4
int ReadSens(int pin) 
{  
  return analogRead(pin);
}
Но даже так смысла мало.
0
0 / 0 / 0
Регистрация: 03.10.2015
Сообщений: 25
16.09.2019, 19:58  [ТС] 3
Как код ни обзывай - он работает! Это все, что тут заметили?
И какой смысл тут Вы ищете?
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
16.09.2019, 20:04 4
Цитата Сообщение от Lavad Посмотреть сообщение
Подходящей темы в разделе не нашел,
не надо искать. Зачем влазить в чужую тему со своими вопросами?
Цитата Сообщение от Lavad Посмотреть сообщение
поэтому создал новую.
правильно сделал
правила п 5.16
Запрещено создавать темы с множеством вопросов во всех разделах, кроме разделов платных услуг. Один вопрос - одна тема.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
16.09.2019, 20:12 5
Цитата Сообщение от Lavad Посмотреть сообщение
Как код ни обзывай - он работает
Хороший слоган быдлокодера.

Добавлено через 1 минуту
Цитата Сообщение от Lavad Посмотреть сообщение
Как код ни обзывай - он работает! Это все, что тут заметили?
И какой смысл тут Вы ищете?
Я задал вопрос. Ответа не вижу. А гадать не умею.

Цитата Сообщение от Avazart Посмотреть сообщение
Что за потенциометр и как его подключали?
Имею ввиду номинал.
0
0 / 0 / 0
Регистрация: 03.10.2015
Сообщений: 25
16.09.2019, 20:43  [ТС] 6
Цитата Сообщение от Avazart Посмотреть сообщение
Что за потенциометр и как его подключали?
Стандартно! Крайние выводы на питание, средний - на аналоговый пин.
Цитата Сообщение от Avazart Посмотреть сообщение
Имею ввиду номинал.
20к.
Какое отношение вдруг номинал имеет к моей проблеме, если скетч "только потенциометр" прекрасно работает?
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
16.09.2019, 21:12 7
Цитата Сообщение от Lavad Посмотреть сообщение
снимать с пина Vin [4.4V]).
А почем у Вас не 5 V ?
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
16.09.2019, 22:06 8
Lavad, утверждать не берусь, но по моему, в AVRке которая и стоит на ардуинке всего один АЦП
на входе стоит мультиплексор который и подключает разные выводы
при малом времени мультиплексирования напряжение на одном выводе влияют на другой, конденсатор внутри стоит
как там написана библиотека я не знаю, может там косяки
попробуй считывать не один раз а несколько
например
C++
1
2
3
4
5
6
7
8
int ReadSens(char pin) {  // функция чтения данных с аналогового входа
 int a1,a2,a3,a4;
 a1 = analogRead(pin); // снимем данные с аналогового входа
  a2 = analogRead(pin); // снимем данные с аналогового входа
 a3 = analogRead(pin); // снимем данные с аналогового входа
 a4 = analogRead(pin); // снимем данные с аналогового входа
   return (a1+a2+a3+a4)/4;            // вернем результат отправителю
}
0
0 / 0 / 0
Регистрация: 03.10.2015
Сообщений: 25
17.09.2019, 00:30  [ТС] 9
Уже проходил:
C++
1
2
3
4
5
6
7
8
9
  int ReadSensa(char pin){   // функция чтения данных с аналогового входа
  byte i;
  int sval = 0;
  for (i = 0; i < 5; i++){
  sval = sval + analogRead(pin);    // 5 раз измерим аналоговый вход
  }
  temp = sval / 5;    // усредним
  return temp;   // вернем результат отправителю
  }
Надеюсь, это то, что Вы имели в виду.
К сожалению, ситуацию не меняет :-(

Добавлено через 21 минуту
Я бы согласился с Вами по поводу емкостей (включая емкости поверхностного монтажа), которые суживают работу контроллера... Но Mega328P спроектирована для работы на частотах до 20 МГц! А тут (на китайской Arduino Uuno r3) всего 16 МГц (если не меньше).
Тем более, проверял с разными аналоговыми входами, которые (на уровне кристалла чипа) отстоят друг от друга на каком-то расстоянии. Значит, и емкости меняются (и не в меньшую сторону).
А библиотека... Тут я пас. Библиотека, уже встроенная в дистрибутив Arduino Uno 1.8.9, скачаный с офиц-сайта arduino.cc... Это уже выше моих пониманий.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
17.09.2019, 06:57 10
Lavad, тут вот еще что есть
Цитата Сообщение от Lavad Посмотреть сообщение
float temp
Цитата Сообщение от Lavad Посмотреть сообщение
temp = ReadSens(Lm35Pin);
Цитата Сообщение от Lavad Посмотреть сообщение
int ReadSens(char pin)
Цитата Сообщение от Lavad Посмотреть сообщение
temp = analogRead(pin)
Цитата Сообщение от Lavad Посмотреть сообщение
return temp;
temp то float то int
на проблему озвученную в теме это вряд ли влияет, но вот потеря точности и производительности есть
1
0 / 0 / 0
Регистрация: 03.10.2015
Сообщений: 25
17.09.2019, 15:37  [ТС] 11
Цитата Сообщение от ValeryS Посмотреть сообщение
temp то float то int
Смешалось все - кони, люди...
Цитата Сообщение от ValeryS Посмотреть сообщение
int ReadSens(char pin)
Да, нестыковочка типов... Функция на целое число, а возвращает дробное .
С другой стороны она все таки выдает float (не пойму, правда, почему с двумя нулями после запятой, вместо одного)
Цитата Сообщение от ValeryS Посмотреть сообщение
на проблему озвученную в теме это вряд ли влияет, но вот потеря точности и производительности есть
Да, проблему не решило, а по поводу точности и производительности...
Продублировал скетч, добавил int-переменную, которую прописал в самой функции измерения и вызове функции. Float осталась только в 2-ух строках:
C++
1
2
3
izmer = ReadSens(Lm35Pin);        // снимем данные с пина Lm35Pin [112...116 мкс]
temp = (izmer * 109.99) / 1024.0; // [28 мкс]
myDisplay(0, 0, 1, "`C", temp);   // отправляем данные на дисплей [16...18 мс]
Измерил время выполнения строк и функций в обоих скетчах. Особой разницы не заметил: цикл loop() в первом скетче выполнялся за 32 мсек, во втором - 31 мсек. Оба скетча потратили один и тот же объем памяти.
Имеются какие-то другие критерии и способы измерения производительности?

Добавлено через 58 минут
Цитата Сообщение от ValeryS Посмотреть сообщение
при малом времени мультиплексирования...
Добавил еще задержки в 0.5сек, перед вызовом следующего измерения (19 строка). Без изменений (ну, кроме тормозов в работе ).
Секунда цикла loop()... при тактах контроллера в микросекунды... это гигантское время. Думаю, время мультиплексирования контроллера тут "не виноватая я!"

Добавлено через 1 час 46 минут
Увы, причина прячется в выборе ИОН
Теперь буду копаться в нем - как убить двух зайцев одним тапком - и пониженное напряжение для точности LM35, и повышенное для, например, потенциометра. Или как-то совместить пониженное 1.1V с потенциометром.

Добавлено через 16 минут
Проблема осталась!
Подтянуть показания термометра не проблема - подкорректировать множитель в строке.
C++
1
temp = (izmer * 498.83) / 1024.0; // при ВЫКЛюченном внутреннем ИОН
Но, как и следовало ожидать, показания не стабильны - +-0.5 град. А это как раз паспортное значение точности LM35.
Совместить пониженное 1.1V с потенциометром (или любым другим схожим источником напряжения до 5V) тоже не проблема - делитель напряжения.
Скачки показаний при повороте переменника такие же, как и в вопросе данной темы.
0
Тутошний я
2146 / 1201 / 225
Регистрация: 03.11.2009
Сообщений: 4,416
Записей в блоге: 2
17.09.2019, 15:41 12
C++
1
PotVal = map(temp, 0, 1023, 0, 100);
Почему до 100, если ион 1,1 вольта?
0
0 / 0 / 0
Регистрация: 03.10.2015
Сообщений: 25
17.09.2019, 21:43  [ТС] 13
Всего лишь для лицезрения на дисплее 0...100%
И потом... То, что величина ИОН повязана с точностью - только сейчас увидел.

Добавлено через 5 часов 57 минут
Что-то упускаю, но за хвост схватить не могу
Для меня было бы объяснением, если бы дерганье показаний происходили при превышении уровня ИОН (на любом из аналоговых входов). Тогда да, можно свалить на перегруз схемы контроллера, отвечающей за обработку аналоговых сигналов. Но нет!
Дерганье начинается уже при 350mV на входе. Вне зависимости от источника питания на потенциометре - линейный блок питания, импульсный или с платы Arduino! Вот этого не догоняю .
А с учетом разнообразия ответов большого количества участвующих в теме... совсем запутался
0
Тутошний я
2146 / 1201 / 225
Регистрация: 03.11.2009
Сообщений: 4,416
Записей в блоге: 2
19.09.2019, 00:32 14
Лучший ответ Сообщение было отмечено Lavad как решение

Решение

Цитата Сообщение от Lavad Посмотреть сообщение
В вышеуказанном скетче уже на 30 градусах поворота показывает 100%.
1,1 вольта от 4,4, наверно так и будет.
Цитата Сообщение от Lavad Посмотреть сообщение
Совместить пониженное 1.1V с потенциометром (или любым другим схожим источником напряжения до 5V) тоже не проблема - делитель напряжения.
настроить ИОН на 1,1 вольта, считать температуру, настроить на 5 вольт, считать потенциометр.

Добавлено через 1 минуту
Провода у потенциометра длинные? Может всё же внешние наводки.
1
Тутошний я
2146 / 1201 / 225
Регистрация: 03.11.2009
Сообщений: 4,416
Записей в блоге: 2
19.09.2019, 10:32 15
Чем больше угол поворота потенциометра, тем больше сопротивление.
По закону Ома, допустим ток от наводок постоянной велечины, а чем больше сопротивлени, тем больше напряжение наводок будет. И соответственно больше скачков.
Попробовать устройство в другой комнате, с более короткими проводами на потенциометр, скрученными в жгут, ...
0
0 / 0 / 0
Регистрация: 03.10.2015
Сообщений: 25
19.09.2019, 16:08  [ТС] 16
Цитата Сообщение от Grey Посмотреть сообщение
настроить ИОН на 1,1 вольта, считать температуру, настроить на 5 вольт, считать потенциометр.
Да, пробовал...
C++
1
2
3
4
5
analogReference(INTERNAL);  // подключаем внутренний ИОН на 1.1V (INTERNAL)
temp = ReadSens(Lm35Pin);         // снимем данные с пина Lm35Pin
...
analogReference(DEFAULT);   // подключаем внутренний ИОН на 5V (DEFAULT)
temp = ReadSens(PotPin);          // снимем данные с пина потенциометра
Чтобы смена ИОН "устаканивалась", добавлял и задержки (1...10мсек), и до и после analogReference(). Без толку!
Далее..., программа, почему-то, в упор не видит запуск внутреннего ИОН. Вся работа проходит с ИОН 5В. Неверно прописал в коде?
P.S. Для потенциометра все отлично, а датчик температуры, разумеется, работает с дискретностью в 0.5мВ (+-0.5град), ну и показания уменьшены в 4.5 раза. Снова менять множитель? Это сейчас я пробую с долями градусов. В конечном итоге, в конструкции будут целые числа. Но при такой дискретности показания будут прыгать уже +-1град. На кой ляд мне такой термометр?

Добавлено через 11 минут
Цитата Сообщение от Grey Посмотреть сообщение
...Может всё же внешние наводки.
Чем больше угол поворота потенциометра, тем больше сопротивление.
По закону Ома,..., с более короткими проводами на потенциометр, скрученными в жгут, ...
Все верно! Теоретически. А практически выиграл немного .
Первоначально провода к потенциометру были 15 см, скрученные (!). Сейчас укоротил до 4см, средним выводом потенциометра непосредственно в пин на Arduino. Сменил и пин - теперь А5, самый дальний от А0.
Показания термометра начинают дергаться при 30% (и больше) поворота потенциометра.
4см провода, плюс корпус потенциометра, плюс плата Arduino... - все, так или иначе, работают приемными антеннами! КАК же собирать конструкции, если они такие нежные и чувствительные?
Что-то тут другое...
P.S. Как будет время, проверю с экранированными проводами.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
19.09.2019, 17:19 17
Лучший ответ Сообщение было отмечено Lavad как решение

Решение

Grey, проблема ТС в том, если я правильно понял,что по отдельности и потенциометр и термометр работают нормально
а как он их включает вместе начинаются чудеса

Добавлено через 1 минуту
Цитата Сообщение от Lavad Посмотреть сообщение
Показания термометра начинают дергаться при 30% (и больше) поворота потенциометра.
осциллограф что показывает, или хотя бы тестер?
пробовал зашунтировать всю эту байду конденсаторами

Добавлено через 25 минут
Lavad, мысли в слух, как я писал на входе АЦП стоит конденсатор, и вот когда ты меряешь значение на потенциометре, то конденсатор заряжается до напряжения на движке,потом мультиплексор переключается на вход термометра а конденсатор остается заряженный, ему бы разрядится но термометр довольно неважная цепь для разряда
Предлагаю такой выход, еще один выход АЦП подцепить на землю, и замеры производить через него
типа
C++
1
2
3
4
5
6
7
temp = ReadSens(gnd);         // фиктивный замер чтобы разрядить конденсатор
.....
temp = ReadSens(Lm35Pin);         // снимем данные с пина Lm35Pin
...
temp = ReadSens(gnd);         // фиктивный замер чтобы разрядить конденсатор
 
temp = ReadSens(PotPin);          // снимем данные с пина потенциометра
1
0 / 0 / 0
Регистрация: 03.10.2015
Сообщений: 25
19.09.2019, 17:41  [ТС] 18
Столько времени забрал своего и чужого!!!
Грязь в питании и эфире! Вот и вся причина (надеюсь, что только это!). Снова наступил на грабли
Спускался в бронированную комнату - показания успокаивались.
Зашунтировал входной пин конденсатором - осцилл показал резкое уменьшение грязи и, как следовательно, стабильность показаний термометра. И это на том самом рабочем столе, с которого все началось.
Комп, блоки питания, проводка и еще черт знает, что у меня тут в 2 кв.метрах творится! Теперь перепланировкой заниматься и экранировать все сетевые провода? Все на заэкранируешь! Елки палки!
За этим самим столом много работал с AVR-ками (под Bascom и USBASP), но ТАКОГО каприза и нежности не наблюдал!
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
19.09.2019, 17:50 19
Цитата Сообщение от Grey Посмотреть сообщение
Чем больше угол поворота потенциометра, тем больше сопротивление.
По закону Ома, допустим ток от наводок постоянной велечины, а чем больше сопротивлени, тем больше напряжение наводок будет. И соответственно больше скачков.
Попробовать устройство в другой комнате, с более короткими проводами на потенциометр, скрученными в жгут, ...
Потенциометр работает как делитель напряжение так что все размышления "о сопротивлении" в топку.

Если переменный резистор старый или выгоревший то он и так может в некоторых положениях создавать "дребезг" это нормально именно по этой причине используют энкодеры а не резисторы.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
19.09.2019, 17:52 20
Цитата Сообщение от Lavad Посмотреть сообщение
За этим самим столом много работал с AVR-ками (под Bascom и USBASP),
не поверишь в ардуне тоже AVR
0
19.09.2019, 17:52
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.09.2019, 17:52
Помогаю со студенческими работами здесь

Найти в серии показаний минимальное произведение двух показаний, между которыми прошло не менее 6 минут
Добрый день, задали по информатике на днях решить следующую задачу: На спутнике «Фотон»...

В компонент Label вывести надпись «произведение показаний» и добавить текущее значение произведения показаний счетчиков
Разместите на форме два компонента Edit и два компонента UpDown. Первый счетчик должен отображать...

Скачки напряжения и скачки загрузки видеокарты
Начали мучать мою видеокарту частые скачки загруженности видеокарты и ее напряжение, при скачках...

СМА BOSCH WFR-2441 ОТСУТСТВУЕТ ИНДИКАЦИЯ НА ДИСПЛЕЕ, При полностью работающей машине отсутствует индикация на дисплее
Доброго времени суток, господа, товарищи, мужчины. Попалась сегодня машина Bosch WFR-2441 (E-NR...

Разница показаний
Сайт работает с августа, счетчики мейла, лайвинтернета, рамблера тпоказывают всреднем по 20-40 чел...

Достоверность показаний температуры
CPUID\HWMonitor показывает везде приемлемую температуру и только SISTIN прямо сразу 122°. Что это?...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru