Одно условие на 4 вывода.

sp34
Offline
Зарегистрирован: 05.03.2013

Имеем условие при котором на одном из четырех выводов будет HIGH на 1

if(XX<XX)

{

digitalWrite(1,HIGH);

digitalWrite(2,LOW);

digitalWrite(3,LOW);

digitalWrite(4,LOW);

}

Далее следующее условие где HIGH на 2

 

if(XX<XX)

{

digitalWrite(1,HIGH);

digitalWrite(2,LOW);

digitalWrite(3,HIGH);

digitalWrite(4,HIGH);

}

И так бесконечное множество , все работает , но при этом код очень грамозкий.

Как правильно написать следуещее.

Комбинаций с digitalWrite (X,HIGH); всего 16 - и я хотелбы их описать как например:

A - это первая комбинация из четырех digitalWrite (X,HIGH), digitalWrite (X,LOW), digitalWrite (X,LOW), digitalWrite (X,LOW);

В - вторая комбинация из четырех digitalWrite (X,HIGH), digitalWrite (X,LOW), digitalWrite (X,HIGH), digitalWrite (X,HIGH);

и.т.д - 16 раз

И после этого переписать условия в виде:

if(X>X)

{

A; - выпоняется комбинация А

}

И.Т.Д - подставляя в условия только имена этих комбинаций.

КАК эти комбинации прописать в коде - незнаю , помогите пожалуйста.

 

maksim
Offline
Зарегистрирован: 12.02.2012

Вынесите в функцию:

void digitalWrites(bool _1, bool _2, bool _3, bool _4,)
{
  digitalWrite(1,_1);
  digitalWrite(2,_2);
  digitalWrite(3,_3);
  digitalWrite(4,_4);
}

и вызывайте ее с нужными параметрами:

if(X > XX) digitalWrites(HIGH, LOW, LOW, LOW);
if(X < XX) digitalWrites(HIGH, LOW, HIGH, LOW);
if(Y > YY) digitalWrites(LOW, LOW, HIGH, LOW);
if(Y < YY) digitalWrites(LOW, LOW, LOW, LOW);

 

sp34
Offline
Зарегистрирован: 05.03.2013

Хорошее решение , но хотелось-бы выводить эти комбинации просто в виде имени  , что бы не прописывать в каждом условии комбинации . т.к эти 4 вывода формируют двоичный код для преобразователя в формате 1-2-4-8 и он уже преобразует его в десятичный от 0 до 15.

где D1 - 1 , D2 - 2 , D3 - 4 , D4 - 8 

своего рода это расшеритель выходов из 4 в 16

и малейшая путаница с комбинацией приведет к неправильному значению.

А если будет в виде имен то написав своего рода библиотечку из 16 условий - ошибка исключена и дальнейшее написание условий будут интуетивно понятным.

maksim
Offline
Зарегистрирован: 12.02.2012

Тогда так:

void digitalWrites(byte _4bit)
{
  digitalWrite(1, _4bit&B0001);
  digitalWrite(2, _4bit&B0010);
  digitalWrite(3, _4bit&B0100);
  digitalWrite(4, _4bit&B1000);
}

////.....

if(X > XX) digitalWrites(0);
if(X < XX) digitalWrites(15);

 

sp34
Offline
Зарегистрирован: 05.03.2013

maksim 

Что то я уже подзапутался  -  при условии в последнем вашем сообщении если я напишу например: digitalWrite(15);

Появятся высокие уровни на всех четырех выходах - так ? или вы описали все выводы ARDUINO 0-15

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

Сложность заключается в том что в условии два , а иногда и три преобразователя 1-2-4-8

т.е сейчас у меня так:

if(x>y)

{

digitalWrite(1,HIGH); // 1

digitalWrite(2,LOW); // 2

digitalWrite(3,LOW); // 4

digitalWrite(4,HIGH);  // 8

получается выход на 1 - ом преобразователе 1+8 = 9

 

digitalWrite(5,HIGH); // 1

digitalWrite(6,HIGH); // 2

digitalWrite(7,HIGH); // 4

digitalWrite(8,LOW); // 8 

Вывод на втором преобразователе 1+2+4 = 7

}

Задействованно 8 ног ARDUINO и на выходе после преобразователей я получил 32.

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

Преобразователи я поставил для экономии цифровых выводов ARDUINO схема уже собрана и на уровне железа не переделать.

 

 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Вы можете просто ввести 16 функций. В каждой из них будет определенная комбинация включения выходов.

Называете функции цифрами и , при выполнении условий , вызываете соответствующие функии.

Что за устройство изобретаете ?

maksim
Offline
Зарегистрирован: 12.02.2012

Я вас не понимаю.
Какие 8 ног? Что? Куда? Чего вы хотите сделать?

Функция void digitalWrites(byte _4bit) принимает число от 0 до 15 и выводит его в бинарном виде на 4 соответсвующих ногах дуины.

sp34 пишет:
если я напишу например: digitalWrites(15); Появятся высокие уровни на всех четырех выходах - так ? 
Так.
Если напишите 
digitalWrites(9); то будет:

digitalWrite(1,HIGH);
digitalWrite(2,LOW);
digitalWrite(3,LOW);
digitalWrite(4,HIGH);  

если напишите digitalWrites(7); то будет:

digitalWrite(5,HIGH);
digitalWrite(6,HIGH); 
digitalWrite(7,HIGH); 
digitalWrite(8,LOW);

все как в вашем десятичном расчете.

sp34
Offline
Зарегистрирован: 05.03.2013

nestandart пишет:

Вы можете просто ввести 16 функций. В каждой из них будет определенная комбинация включения выходов.

Называете функции цифрами и , при выполнении условий , вызываете соответствующие функии.

Вы немоглибы мне простой примерчик показать - я пока совсем двоешник в C++

 Приборчик - нет не приборчик - перехватываю сиглал с АЦП и изменяя его параметры относительно трех условий температуры отправляю его назад .

 

 

sp34
Offline
Зарегистрирован: 05.03.2013

maksim пишет:

все как в вашем десятичном расчете.

Сейчас попробую спасибо , но непойму как описать два преобразования - 8 ног или три преобразования 12 ног ARDUINO !

т.е мне нужна функция digitalWrive(15) 0-15 - для одного преобр. и для другого нужна комбинация вторая типа digitalWrite 2(15) 0-15 также и т.д

maksim
Offline
Зарегистрирован: 12.02.2012

Да, в каждой функции будут указаны свои ноги.

sp34
Offline
Зарегистрирован: 05.03.2013

maksim пишет:

Да, в каждой функции будут указаны свои ноги.

 

Т.е digitalWrites  - я могу обозвать как угодно для одного и по другому для другого преобразователя. ТАК ?

В каком месте кода нужно создать эту функцию ? - ругается при компиляции.

maksim
Offline
Зарегистрирован: 12.02.2012
void setup() {
  // put your setup code here, to run once:

}

void loop() {
  Converter1(2);
  Converter2(9);
  Converter3(15);  
  Converter1(8);
  Converter3(10);
}

void Converter1(byte _4bit)
{
  digitalWrite(1, _4bit&B0001);
  digitalWrite(2, _4bit&B0010);
  digitalWrite(3, _4bit&B0100);
  digitalWrite(4, _4bit&B1000);
}

void Converter2(byte _4bit)
{
  digitalWrite(5, _4bit&B0001);
  digitalWrite(6, _4bit&B0010);
  digitalWrite(7, _4bit&B0100);
  digitalWrite(8, _4bit&B1000);
}

void Converter3(byte _4bit)
{
  digitalWrite(9, _4bit&B0001);
  digitalWrite(10, _4bit&B0010);
  digitalWrite(11, _4bit&B0100);
  digitalWrite(12, _4bit&B1000);
}

 

sp34
Offline
Зарегистрирован: 05.03.2013

Спасибо !!!  все получилось - код сократился на 25%

sp34
Offline
Зарегистрирован: 05.03.2013

Как вывести через Serial.print  в десятичном виде значение Converter1 из примера выше от maksim  - чтобы мониторить данное значение для диагностики.

maxi_10
Offline
Зарегистрирован: 05.01.2012
leshak
Offline
Зарегистрирован: 29.09.2011

Никак. В его примере Converter1 - это функция. К тому же не возвращающая значения. Следовательно с какой стороны не посмотри - выводить нечего.

Вы явно хотите выводить что-то другое. Но что?

А еще можете почитать Управление портами через регистры Atmega | Аппаратная платформа Arduino  может этот подход окажется проще (правда менять ноги уже так просто не выйдет). Но с подходом Максима - тоже разберитесь. В идеале нужно знать оба (каждый имеет свои плюсы и минусы).

leshak
Offline
Зарегистрирован: 29.09.2011

А еще, можно делать вызовы этих функций не десятичными константами

Converter2(9);

А двоичным

Converter2(B1001);

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

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

ConvertX(B1111) или ConvertX(15)  //что одно и тоже

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

1. 0000 - изначалное
2. 0001
3. 0011
4. 0111
5. 1111

Состояние со второго по четвертое будут существовать микросекунды, но они будут. В некоторых случаях это критично и нужен четкий переход от 0000 к 1111, без этих промежуточных. Тогда выход - только через прямую запись в порт.
 

sp34
Offline
Зарегистрирован: 05.03.2013

leshak пишет:

Вы явно хотите выводить что-то другое. Но что?

При разных многочисленных условиях изменяется число в Converter1 от 0-16 и на 4-х цифровых выходах появляется двоичная комбинация. - вот ее я и хочу видеть в мониторинге и если возможно в десятичном виде.

Я могу Serial.print прописать в каждом из условий но это не вариант их очень много и код получается громоский. - место экономлю.

Переход не критичен от 2-4 значению я вас понял.

leshak
Offline
Зарегистрирован: 29.09.2011

 

sp34 пишет:

При разных многочисленных условиях изменяется число в Converter1 от 0-16 и на 4-х цифровых выходах появляется двоичная комбинация. - вот ее я и хочу видеть в мониторинге и если возможно в десятичном виде.

Так какое- же число? _4bit?  Это называется "параметр функции". Не хотите писать Serial.println при каждом вызове Converter1?

Ну так сделайте его внутри функции, там же где и digitalWrite

Serial.println(_4bit,DEC);

Хотя DEC тут и не обязательно, по умолчанию и так все в десятичном вывоидтся. Только зачем тут десятичный? Не очень понятно. Что-бы потом "переводить в уме" какие ноги выставляются? IMHO в двоичном было-бы удобней выводить (вам выше ссылку дали на документацию, посмотрите как это делается). А можно и в двоичном и десятичном выводить :) На все случаи жизни  (два Serial.print делать)

sp34
Offline
Зарегистрирован: 05.03.2013

leshak пишет:

Так какое- же число? _4bit?  Это называется "параметр функции". Не хотите писать Serial.println при каждом вызове Converter1?

Ну так сделайте его внутри функции, там же где и digitalWrite

Serial.println(_4bit,DEC);

Спасибо ! прописал в нутри функции и все вывелось , а десятичное число мне нужно для того - далее эти 4-вывода управляют конвертером (1-2-4-8) двоичного кода в десятичный. - анализировать какой вывод включится на конверторе мне удобнее в десятичном виде.

leshak
Offline
Зарегистрирован: 29.09.2011

А если цель "экономить" - то можно свернуть пример Максима во так, использовать одну функцию вместо 4-рех и передавать ей какими пинами рулить (просто Максим давал пример "попроще для понимания"):

Через дефайны

#define PINS_SET1 1,2,3,4
#define PINS_SET2 5,6,7,8
#define PINS_SET3 9,10,11,12


void setup() {
  // put your setup code here, to run once:

}

void loop() {
  Converter(2,PINS_SET1);
  Converter(9,PINS_SET2);
  Converter(15,PINS_SET3);
  Converter(8,PINS_SET1);
  Converter(10,PINS_SET3);

}

void Converter(byte _4bit,byte pin1, byte pin2,byte pin3, byte pin4)
{
  digitalWrite(pin1, _4bit&B0001);
  digitalWrite(pin2, _4bit&B0010);
  digitalWrite(pin3, _4bit&B0100);
  digitalWrite(pin4, _4bit&B1000);
}

Или через массивы:

byte PINS[][4]={
  {1,2,3,4},
  {5,6,7,8},
  {9,10,11,12}
};

void setup(){
  // обратите внимание что индекс какой набор пинов использовать, начинается с нуля
  Converter(2,0);
  Converter(9,1);
  Converter(15,2);
  Converter(8,0);
  Converter(10,2);
}

void loop(){
}

void Converter(byte _4bit,byte pinSetIndex){ // pinSetIndex - какой набор пинов использовать
  for(byte i=0;i<4;i++)digitalWrite(PINS[pinSetIndex][i],bitRead(_4bit,i));
}

не проверял, но суть идеи думаю ясна (если не ясна - читать документацию про массивы и справочники C про #define)

leshak
Offline
Зарегистрирован: 29.09.2011

Ах, да забыл традиционное - новичкам нужно читать прикрепленные ветки Вставка программного кода в тему/комментарий

sp34
Offline
Зарегистрирован: 05.03.2013

Спасибо ! будем учиться !

leshak
Offline
Зарегистрирован: 29.09.2011

Или вот еще вариация. Упрощенный вариант массивов, но без двух-мерных (массив, массивов), только одномерный (возможно проще для понимания).

 

byte PINS1[]={1,2,3,4};
byte PINS2[]={5,6,7,8};
byte PINS3[]={9,10,11,12};

void setup(){
 
  Converter(2,PINS1);
  Converter(9,PINS2);
  Converter(15,PINS3);
  Converter(8,PINS1);
  Converter(10,PINS3);
}

void loop(){
}

void Converter(byte _4bit,byte pins[]){ 
  for(byte i=0;i<4;i++)digitalWrite(pins[i],bitRead(_4bit,i));
}