Помогите с проэктом

dexterplay101
Offline
Зарегистрирован: 22.03.2018

Добрый день всем!

Прошу помочь с проэктом а в частности с кодом.

И так...

Задумка следующая:

Имеем датчик показания которого должна обрабатывать ардвино.

На выходе датчик выдаёт напряжение от 0.00V до 1.00V,миливольты так же важны в показаниях.

В качестве показометра выступают светодиоды в колличестве 10 штук(если возможно 10).

Требуется выводить на светодиоды показания напряжения датчика с дискретностью 0.1mМ.

В диапазоне показаний  0.00-0.10mV загорается 1 Led ,от 0.10-0.20mV 2 Led ... этакая шкала.

В Aduino не силён-только осваиваю...

Думаю так:

в начале кода назначаю A0 входным аналоговым пином а пины 12-3 выходными пинами

назначаю переменную с показаниями с A0

далее процедурой loop снимаем постоянно показания с A0 и дискретно обработав по заданным рамкам выводим на Led соответствующий этому диапазону напряжения?

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

А в чём Вам нужна помощь?

dexterplay101
Offline
Зарегистрирован: 22.03.2018

Помощь в поавильном написание кода,составление логики программы,приходиться вспоминать школьные курсы информатики,рисовать блок схемы выписывать переменные...

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

Ну, Вы начните что-то делать. Когда человек сам ничего не делает, то это называется не "помощь", а "делать за него". Или Вам это и надо?

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

dexterplay101 пишет:
На выходе датчик выдаёт напряжение от 0.00V до 1.00V,миливольты так же важны в показаниях.
С дефолтным значением опорного, минимальное значение попугая АЦП около 5мВ. Значит потребуется задействовать внутренний опорник в 1.1В. Тогда и получите примерно 0.1мВ.

dexterplay101
Offline
Зарегистрирован: 22.03.2018

Нет конечно,за меня делать не нужно,просто хотел услышать какие то советы знающих в этом деле людей заранее,в частности если ли на ардвино какая то нижняя граница на аналоговом входе.Где то читал что там присутствует 0.6mV.кстате железка будет nano atmega 168

dexterplay101
Offline
Зарегистрирован: 22.03.2018

Вот уже дельная информация,спасибо,буду изучать матчасть)))

b707
Онлайн
Зарегистрирован: 26.05.2017

dexterplay101 пишет:

кстате железка будет nano atmega 168

На нано вроде не бывает atmega168 , только 328

dexterplay101
Offline
Зарегистрирован: 22.03.2018
dexterplay101
Offline
Зарегистрирован: 22.03.2018

b707 пишет:

dexterplay101 пишет:

кстате железка будет nano atmega 168

На нано вроде не бывает atmega168 , только 328

плохо видно на фото но есть две версии 168 и 328

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Ссылкой нагляднее ))

dexterplay101
Offline
Зарегистрирован: 22.03.2018

Получился такой вот скетч:

int analogPin = 1; //устанавливаем пин для датчика 
int vol = 0;  //переменная для записи значения с входа
int LedPin0= 12; // пин выхода светодиода 0
int LedPin1= 11; // пин выхода светодиода 1
int LedPin2= 10; // пин выхода светодиода 2
void setup() 
{
 Serial.begin(9600); //соединение
  pinMode(LedPin0,OUTPUT); //Ledпины работают выходом
  pinMode(LedPin1,OUTPUT);
  pinMode(LedPin2,OUTPUT);
 
 //индикация включения(моргаем 3мя диодами по очереди) 
  
  digitalWrite(LedPin0,HIGH); //включаем диод 0
  delay(500);// ждем 0,5 сек
  digitalWrite(LedPin0,LOW); //выключаем
  delay(500); //ждем 0,5 сек
 
  digitalWrite(LedPin1,HIGH); //включаем диод 1
  delay(500);// ждем 0,5 сек
  
  delay(500); //ждем 0,5 сек
 
    digitalWrite(LedPin2,HIGH); //включаем диод 2
  delay(500);// ждем 0,5 сек
  digitalWrite(LedPin2,LOW); //выключаем
  delay(500); //ждем 0,5 сек
}
 
void loop() 
{
analogReference(INTERNAL);//встроенное опорное напряжение 1.1 В для аналогового входа
vol=analogRead(analogPin);//значение с входа записали в переменную
 
 if (vol >= 0 and vol <=341)  //Если значение на входе больше или равно 0 и меньше или равно 341 включаем диод 0
 digitalWrite(LedPin0,HIGH) ;
  
  if (vol >= 341 and vol <=682)   //Если значение на входе больше или равно 341 и меньше или равно 682 включаем диод 1
 digitalWrite(LedPin1,HIGH); 
 
  if (vol >= 682 and vol <=1023)   //Если значение на входе больше или равно 682 и меньше или равно 1024 включаем диод 1
 digitalWrite(LedPin2,HIGH); 
 
 
if (vol >1024)  //в случае превышения напряжения на входе моргаем ледом 1
digitalWrite(LedPin1,HIGH);
delay(500);
digitalWrite(LedPin1,LOW);
delay(500);
digitalWrite(LedPin1,HIGH);
delay(500);
digitalWrite(LedPin1,LOW);
delay(500);
 
 }
 
 
Вот только не соображу как написать что бы при сработки каждого последующего леда выключался предыдущий
 
 
ven-til
Offline
Зарегистрирован: 13.02.2018

dexterplay101 пишет:

Вот только не соображу как написать что бы при сработки каждого последующего леда выключался предыдущий

А в принципе как работает это код уже более-менее устравивает?

kalapanga
Offline
Зарегистрирован: 23.10.2016

Код надо вставлять по правилам. Это не прихоть, без номеров строк его реально невозможно обсуждать. Последнее в скетче мигание нужно было бы взять в фигурные скобки (сейчас к if-у относится только следующая за ним строка, а остальные только портят картину). Но весь этот if не имеет смысла. analogread не вернёт больше 1023. Выкидывайте всё от этого if и до конца, потом скажете, что горит не так, как хотелось бы.

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

analogReference(INTERNAL)
в сетап закиньте, это достаточно только раз сделать...

dexterplay101 пишет:
что бы при сработки каждого последующего леда выключался предыдущий

Ну если следующий включаете HIGH, то предыдущий зжесь же и выключайте - LOW.

dexterplay101
Offline
Зарегистрирован: 22.03.2018

kalapanga пишет:

Код надо вставлять по правилам. Это не прихоть, без номеров строк его реально невозможно обсуждать. Последнее в скетче мигание нужно было бы взять в фигурные скобки (сейчас к if-у относится только следующая за ним строка, а остальные только портят картину). Но весь этот if не имеет смысла. analogread не вернёт больше 1023. Выкидывайте всё от этого if и до конца, потом скажете, что горит не так, как хотелось бы.

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

dexterplay101
Offline
Зарегистрирован: 22.03.2018

OlegK пишет:

analogReference(INTERNAL)
в сетап закиньте, это достаточно только раз сделать...

dexterplay101 пишет:
что бы при сработки каждого последующего леда выключался предыдущий

Ну если следующий включаете HIGH, то предыдущий зжесь же и выключайте - LOW.

изначально так и написал,но последовательность загорания может быть разной а я выключу конкретный диод или Вы предлогаете прописать HIGH для нужного и LOW для остальных двух?Просто сейчас скетч на 3и диода для простоты составления,в идеале хотелось бы 10ть диодов и тогда придется писать 10 строк с описанием HIGH на 1н нужный и 9 LOW?

p.s. Скетч пишу первый раз,до этого не было опыта.

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Тогда проще будет оформить кусок кода, гасящий все светодиоды в самостоятельный кусок кода - функцию.
Перед зажиганием любого светодиода вызываете эту ф-ю и включаете только нужный.

и ещё, какой, по вашему, светодиод будет светить, если значение АЦП будет 341?

  if (vol >= 0 and vol <=341)  
 digitalWrite(LedPin0,HIGH) ;
  
  if (vol >= 341 and vol <=682)
 digitalWrite(LedPin1,HIGH); 
dexterplay101
Offline
Зарегистрирован: 22.03.2018

Видимо нужно так <==341?

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Да нет же.
У вас при 341 совпадёт условие в первом случае и запустит светодиод 0.
Но и далее, 341 также будет удовлетворять следующему условию и засветит светодиод 1.
Очевидно, что где-нибудь нужно убрать одно равно и оставить только знак больше или меньше.
Вот так, например.

if (vol >= 0 and vol <=341)  
...
 if (vol > 341 and vol <=682)
...

 

dexterplay101
Offline
Зарегистрирован: 22.03.2018

Да верно,упущение мое,благодарю за поправку!

dexterplay101
Offline
Зарегистрирован: 22.03.2018
void LedOn(int n) //создание функции с параметром n (номер светодиода)
{
if (n == 0) // позиция 1 
{
digitalWrite(LedPin0, HIGH);
digitalWrite(LedPin1, LOW);
digitalWrite(LexPin2, LOW);
}
else if (n == 1)// позиция 2
{
digitalWrite(LedPin0, LOW);
digitalWrite(LedPin1, HIGH);
digitalWrite(LexPin2, LOW);
}
else if(n== 2) // позиция 3
{
digitalWrite(LedPin0, LOW);
digitalWrite(LedPin1, LOW);
digitalWrite(LexPin2, HIGH);
}

void setup()
{

}

void loop()
{
ledOn(0); //вызов функции с параметром 0 ( первый светодиод)
delay(1000);
ledOn(1); //вызов функции с параметром 1 ( второй светодиод)
delay(1000);
ledOn(2); //вызов функции с параметром 2 ( третий светодиод)
delay(1000);
}

 

dexterplay101
Offline
Зарегистрирован: 22.03.2018

Вот так я представляю реализацию

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Я имел ввиду не так.  На примере Вашего предыдущего -


void loop()  {
    vol = analogRead(analogPin);
    offLeds(); // всё выключаем и ниже включаем нужный
    if (vol >= 0 and vol <341)  { digitalWrite(LedPin0,HIGH) ; }
    if (vol >= 341 and vol <682)  { digitalWrite(LedPin1,HIGH); }
    if (vol >= 682 and vol <=1023)  { digitalWrite(LedPin2,HIGH); }
 }

void offLeds() { 
    digitalWrite(LedPin0, LOW) ; 
    digitalWrite(LedPin1, LOW) ; 
    ...
    digitalWrite(LedPinX, LOW) ; 
}
andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Для 10 светодиодов:

loop() {
  byte vol = analogRead(AnalogPin)/103;
  for(byte i = 0; i < 10; i++)
    digitalWrite(LedPin0 - i, i == vol);
}

 

ven-til
Offline
Зарегистрирован: 13.02.2018

А если диапазоны для диодов одинаковые то можно обойтись функцией мар

void loop()  {
	vol = analogRead(analogPin);
	pinNumber = map(vol, 0, 1023, 10, 19);
	digitalWrite(pinNumber,HIGH);
	offLeds(pinNumber);
}

void offLeds(byte pinNumber) {
	for (byte i = 10; i<20; i++) {
		if (i != pinNumber) digitalWrite(i, LOW) ;
	}
}

 

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Ну вот, пришли, накидали готового... А как же человеку помучиться-поучиться самому?
ven-til, подозреваю, что у ТС следующим вопросом будет, как вместо 10-19 прописать свои пины с 3 по 12-й ))

ven-til
Offline
Зарегистрирован: 13.02.2018

OlegK пишет:

Ну вот, пришли, накидали готового... А как же человеку помучиться-поучиться самому?
ven-til, подозреваю, что у ТС следующим вопросом будет, как вместо 10-19 прописать свои пины с 3 по 12-й ))

Накидали пищу для размышлений с разными подходами, вдруг сподвигнет к лучшему, большому и светлому ))

А по поводу пинов я предложу использовать вычитание  realPin = 12-(pinNumber - 10)  чтоб запутать окончательно.

 

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

OlegK пишет:

Ну вот, пришли, накидали готового... 

Дык, дата ж 23.03. Сегодня, так и быть, можно :(

dexterplay101
Offline
Зарегистрирован: 22.03.2018

ven-til пишет:

dexterplay101 пишет:

Вот только не соображу как написать что бы при сработки каждого последующего леда выключался предыдущий

А в принципе как работает это код уже более-менее устравивает?

Плата еще не пришла,поэтому возможности проверить пока нет а покупать в чип и дипе в 3 раза дороже не хочется.

dexterplay101
Offline
Зарегистрирован: 22.03.2018

map интересная функция,нужно с ней разобраться,но вижу что здорово оптимизирует код и упрощает

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Тут тоже много чего офигительного почитать )))

dexterplay101
Offline
Зарегистрирован: 22.03.2018

Пользуюсь,читаю,но на конкретном примере лучше доходит)

fogary
Offline
Зарегистрирован: 05.03.2016

dexterplay101 пишет:

На выходе датчик выдаёт напряжение от 0.00V до 1.00V,миливольты так же важны в показаниях.

В качестве показометра выступают светодиоды в колличестве 10 штук(если возможно 10).

Требуется выводить на светодиоды показания напряжения датчика с дискретностью 0.1mМ.

В диапазоне показаний  0.00-0.10mV загорается 1 Led ,от 0.10-0.20mV 2 Led ... этакая шкала.

Точно с дискретностью 0,1 мВ (0,0001 В), или все таки 0,1 В? Иначе как бы 10 светодиодов не хватит.

dexterplay101
Offline
Зарегистрирован: 22.03.2018

fogary пишет:

dexterplay101 пишет:

На выходе датчик выдаёт напряжение от 0.00V до 1.00V,миливольты так же важны в показаниях.

В качестве показометра выступают светодиоды в колличестве 10 штук(если возможно 10).

Требуется выводить на светодиоды показания напряжения датчика с дискретностью 0.1mМ.

В диапазоне показаний  0.00-0.10mV загорается 1 Led ,от 0.10-0.20mV 2 Led ... этакая шкала.

Точно с дискретностью 0,1 мВ (0,0001 В), или все таки 0,1 В? Иначе как бы 10 светодиодов не хватит.

Хотелось бы  не равномерную шкалу если говорить о 10 диодах, в середине с более мелким делением(которое еще нужно будет откалибровать) , поэтому возможность устанавливать диапазон привязаный к пину Леда упрощает эту калибровкую.График напряжения датчика

dexterplay101
Offline
Зарегистрирован: 22.03.2018
 void loop()  {

      vol = analogRead(analogPin);

      offLeds(); // всё выключаем и ниже включаем нужный

      if (vol >= 0 and vol <341)  { digitalWrite(LedPin0,HIGH) ; } //если соответствует условию включаем

      if (vol >= 341 and vol <682)  { digitalWrite(LedPin1,HIGH); }//если соответствует условию включаем

      if (vol >= 682 and vol <=1023)  { digitalWrite(LedPin2,HIGH); }//если соответствует условию включаем
   }

  void offLeds() {
 digitalWrite(LedPin0, LOW) ;
 digitalWrite(LedPin1, LOW) ;
 digitalWrite(LedPin2, LOW) ;

  }

 

после выполнения условия в void loop() и включения нужного диода функция void offLeds() ведь выключит его ???

 

 

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Дык по коду -  сперва прочитается значние со входа, затем вырубятся все светодиоды, затем включится нужный, согласно величине.
И так по кругу.
Выключение можете чуток укоротить, через цикл, как выше писали

void offLeds() {
	for ( byte i = 3; i <= 12; i++ ) { digitalWrite(i, LOW) ; }
}
andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

OlegK пишет:

Дык по коду -  сперва прочитается значние со входа, затем вырубятся все светодиоды, затем включится нужный, согласно величине.
И так по кругу.
Выключение можете чуток укоротить, через цикл, как выше писали

void offLeds() {
	for ( byte i = 3; i <= 12; i++ ) { digitalWrite(i, LOW) ; }
}

Неправильно это.

Сначала определяем, какой светодиод должен гореть, а потом - за один проход - зажигаем только его, а остальные гасим. Отдельная процедура для гашения всех светодиодов:

- идеологически вредна,

- перерасходует ресурсы,

- приводит к мерцанию.

Как это сделать, я писал в посте №24. Это не фрагмант, это полный код loop() со всеми вспомогательными функциями.

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

andriano пишет:
Неправильно это.

Скорее всего это так, но для обеспечения нелинейности шкалы (как хочет ТС) всё равно придётся чем-то жертвовать.
Да и вся тема пользы для автора пока не несёт, ибо даже девайса, на котором можно что-то проверить у него нет.

dexterplay101
Offline
Зарегистрирован: 22.03.2018

Девайс в пути,но думаю что не дождусь и куплю в чип и дип на днях

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

OlegK пишет:

andriano пишет:
Неправильно это.

Скорее всего это так, но для обеспечения нелинейности шкалы (как хочет ТС) всё равно придётся чем-то жертвовать.

Отнюдь.

Это совершенно другая задача.

Первая задача - определить, какой именно из светодиодов нужно зажигать. И в этой задаче может фигурировать нелинейность шкалы и пр.

И вторая задача - индикация: нужно просто зажечь выбранный светодиод и потушить остальные.

Моя ремарка касалась исключительно второй задачи.

Если интерес представляет первая, то тут тоже несколько вариантов решения. В первую очередь это аналитическая аппроксимация и табличная фкнкция.

OlegK пишет:

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

Напротив.
Пока едет девайс, самое время осмыслить задачу, составить алгоритм решения, а также разработать константное обеспечение - будь то массив сеточной функции или набор коэффициентов в аппроскимирующей зависимости.