Включить несколько портов одновременно

FF_Group
Offline
Зарегистрирован: 13.12.2015

Добрый день

подскажите простой вопрос как одновременно изменить состояние скажем 10 портов

вот так напрмер это можно записать?

digitalWrite((5,6,7,8,9,10), LOW);

И второй вопрос,

Мне нужно 2 раза в день на время 20-60 секунд включить 1 нагрузку.

А вот время это уже подбирается методом "полевых испытаний", поэтому решил прописать в лоб все порты по очереди на разный интервал.

001void setup() {
002        
003    pinMode(2,OUTPUT);
004    pinMode(3,OUTPUT);
005    pinMode(4,OUTPUT);
006    pinMode(5,OUTPUT);
007    pinMode(6,OUTPUT);
008    pinMode(7,OUTPUT); 
009    pinMode(8,OUTPUT);
010    pinMode(9,OUTPUT);
011    pinMode(10,OUTPUT);
012    pinMode(11,OUTPUT);
013    pinMode(12,OUTPUT);
014    pinMode(13,OUTPUT);    }
015 
016 
017void loop()
018//запускаем в 0:00 ночи
019{
020  digitalWrite(13, HIGH);
021  digitalWrite(12, HIGH);
022  digitalWrite(11, HIGH);
023  digitalWrite(10, HIGH);
024  digitalWrite(9, HIGH);
025  digitalWrite(8, HIGH);
026  digitalWrite(7, HIGH);
027  digitalWrite(6, HIGH);
028  digitalWrite(5, HIGH);
029  digitalWrite(4, HIGH); 
030  digitalWrite(3, HIGH); 
031  digitalWrite(2, HIGH); 
032 
033//пауза с 12 часов ночи до 8 утра
034delay(28800000); // 8*60*60*1000);
035   
036  digitalWrite(13, LOW);
037  delay(1000);
038  digitalWrite(12, LOW);
039  delay(1000);
040  digitalWrite(11, LOW);
041  delay(1000);
042  digitalWrite(10, LOW);
043  delay(1000);
044  digitalWrite(9, LOW);
045  delay(1000);
046  digitalWrite(8, LOW);
047  delay(1000);
048  digitalWrite(7, LOW);
049  delay(1000);
050  digitalWrite(6, LOW);
051  delay(1000);
052  digitalWrite(5, LOW);
053  delay(1000);
054  digitalWrite(4, LOW);
055  delay(1000);
056  digitalWrite(3, LOW);
057  delay(1000);
058  digitalWrite(2, LOW);
059  delay(1000);
060   
061  digitalWrite(13, HIGH);
062  digitalWrite(12, HIGH);
063  digitalWrite(11, HIGH);
064  digitalWrite(10, HIGH);
065  digitalWrite(9, HIGH);
066  digitalWrite(8, HIGH);
067  digitalWrite(7, HIGH);
068  digitalWrite(6, HIGH);
069  digitalWrite(5, HIGH);
070  digitalWrite(4, HIGH); 
071  digitalWrite(3, HIGH); 
072  digitalWrite(2, HIGH); 
073 
074   
075  //пауза с (8 утра +12сек до 18 вечера
076delay(35988000); // 10*60*60*1000 -12000);
077  
078     
079  digitalWrite(13, LOW);
080  delay(1000);
081  digitalWrite(12, LOW);
082  delay(1000);
083  digitalWrite(11, LOW);
084  delay(1000);
085  digitalWrite(10, LOW);
086  delay(1000);
087  digitalWrite(9, LOW);
088  delay(1000);
089  digitalWrite(8, LOW);
090  delay(1000);
091  digitalWrite(7, LOW);
092  delay(1000);
093  digitalWrite(6, LOW);
094  delay(1000);
095  digitalWrite(5, LOW);
096  delay(1000);
097  digitalWrite(4, LOW);
098  delay(1000);
099  digitalWrite(3, LOW);
100  delay(1000);
101  digitalWrite(2, LOW);
102  delay(1000);
103   
104  digitalWrite(13, HIGH);
105  digitalWrite(12, HIGH);
106  digitalWrite(11, HIGH);
107  digitalWrite(10, HIGH);
108  digitalWrite(9, HIGH);
109  digitalWrite(8, HIGH);
110  digitalWrite(7, HIGH);
111  digitalWrite(6, HIGH);
112  digitalWrite(5, HIGH);
113  digitalWrite(4, HIGH); 
114  digitalWrite(3, HIGH); 
115  digitalWrite(2, HIGH); 
116   
117  //пауза с 18 вечера +12 сек до 0 ночи
118delay(21588000); // 6*60*60*1000 -12000);

вот так пока выглядит код (секунды то я поправлю до нужных величин), писарь я еще тот...

Муж_Долговой
Муж_Долговой аватар
Offline
Зарегистрирован: 07.10.2018

 

http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry

Это для начала. Астальное в литературе и примерах.. 

Green
Offline
Зарегистрирован: 01.10.2015

Муж_Долговой пишет:

http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry

Это для начала. Астальное в литературе и примерах.. 


Это сложно для начинающего. Тем более что ему не нужно СТРОГО одновременно.) Проще в цикле:
 

1const byte key[]   = {9,10,11,12,14,15,16,17,18,19};
2 
3  for (byte i = 0; i < sizeof(key); i++){
4    pinMode(key[i], INPUT_PULLUP);

 

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

FF_Group пишет:

подскажите простой вопрос как одновременно изменить состояние скажем 10 портов

Видимо, имелось в виду "пинов".

Ответ: никак, от слова "совсем никак".

Одновременно можно менять только те пины, которые на одном порте сидят (а таких не более 8-ми по определению). Если это устраивает, то Вам уже дади ссылку. Ну и библиотека есть.

Муж_Долговой
Муж_Долговой аватар
Offline
Зарегистрирован: 07.10.2018

Green пишет:

Это для начала. Астальное в литературе и примерах.. 


Это сложно для начинающего. Тем более что ему не нужно СТРОГО одновременно.) Проще в цикле:

[/quote]

Какой же он начинающий? Четыре года на сайте.

sadman41
Offline
Зарегистрирован: 19.10.2016

4 года не срок... Тут вон люди регистрируются чтобы курсовую нахаляву заполучить, не справляются, идут в армию... там ещё на второй год пару раз остаются и всё, четыре года пролетели как миг ;)

Муж_Долговой
Муж_Долговой аватар
Offline
Зарегистрирован: 07.10.2018

Вернувшись к теме .... управлять регистрами прямыми командами не сложно. Один раз разобраться с двоичным счётом пинов в порту и  расположением самих портов.

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

Опять же некоторые библиотеки уже прописаны с определёнными пинами прописаны.

Сложно перенести скетч на другой МК.

Но в приведённом автором скетче конечно же регистрами управлять само проситься.

Моё мнение: Если все пины одновременно надо включать - выключать - надо в корне концепцию всего устройства менять.

sadman41
Offline
Зарегистрирован: 19.10.2016

Конечно надо. Поставить сдвиговый регистр с защёлкой, например.

FF_Group
Offline
Зарегистрирован: 13.12.2015

спасибо за ответы

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

Возвращаюсь к вопросу.

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

еще есть вопрос

вот так можно паузы писать? То есть сразу в скобках проводить арифметические действия?

 

01void setup() {
02    int T;
03    T=10000;
04 
05void loop()
06 {
07 
08//пауза с 12 часов ночи до 8 утра
09delay( 8*60*60*1000);
10 
11digitalWrite(13, LOW);
12  delay(T);
13 delay(T+1000);
14}

 

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

паузы так писать можно, но остальной код совершенно нерабочий. Переменная Т определена в setup и потому в loop работать не будет. Сам setup не закрыт...

Ну и вообще, если вы будуете задавать время с помощью delay() - больше одного реле у вас в проекте работать не будет, а в первом сообщении вам вроде требовалось много портов

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

Да и строка №9. Формально-то оно правильно, но выглядит просто страшно.

FF_Group
Offline
Зарегистрирован: 13.12.2015

b707 пишет:

остальной код совершенно нерабочий. Переменная Т определена в setup и потому в loop работать не будет. Сам setup не закрыт...

вопрос только в незакрытом сетапе? или переменную надо из сетапа вынести выше?

b707 пишет:
если вы будуете задавать время с помощью delay() - больше одного реле у вас в проекте работать не будет, а в первом сообщении вам вроде требовалось много портов

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

 

а вобще сейчас в голову пришла еще мысль.

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

реле управляет мотором шнека.

нажимаем кнопку, считаем время, глазами с весами ждем пока шнек нагрузит необходимую дозу материала. отпускаем кнопку, записываем значение времени T в EEPROM.

только это я буду месяц писать;)

bwn
Offline
Зарегистрирован: 25.08.2014

FF_Group пишет:

только это я буду месяц писать;)

Если почитаете статьи в секретном блоге, то все пойдет быстрее.

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

ЕвгенийП пишет:

Да и строка №9. Формально-то оно правильно, но выглядит просто страшно.

А оно точно формально правильно?

У меня - выводит 29696.

1void setup() {
2  Serial.begin(115200);
3}
4 
5void loop() {
6  Serial.println(8*60*60*1000);
7  delay(1000);
8}

 

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

Точно правильно. У Вас неудачный тест. Параметр delay описан как uint32_t, поэтому корректный тест выглядит так:

01void setup() {
02    Serial.begin(115200);
03}
04 
05void __delay(uint32_t d) {
06    Serial.println(d);
07}
08 
09void loop() {
10    __delay(8*60*60*1000);
11    delay(1000);
12}

 

Green
Offline
Зарегистрирован: 01.10.2015

Во блин. Я тоже на этом попался.( Век живи - век учись.(

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

ЕвгенийП пишет:

Точно правильно. У Вас неудачный тест. Параметр delay описан как uint32_t, поэтому корректный тест выглядит так:

01void setup() {
02    Serial.begin(115200);
03}
04 
05void __delay(uint32_t d) {
06    Serial.println(d);
07}
08 
09void loop() {
10    __delay(8*60*60*1000);
11    delay(1000);
12}

Странно это.

А по моей логике сначала должны проводться вычисления в int, и только потом получившееся 29696 приводится к типу uint32_t. И, кстати, натурные эксперименты это подтверждают, - вывод не поменялся.

 

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

Да, наверное, это меня переклинило. Может, о другом думал.

Green
Offline
Зарегистрирован: 01.10.2015

Ага. Сбивают тут, понимаешь, с пути истинного, своим авторитетом.) Достаточтно что бы один из операндов был int32_t, даже без явного указания.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Green пишет:

Ага. Сбивают тут, понимаешь, с пути истинного, своим авторитетом.) Достаточтно что бы один из операндов был int32_t, даже без явного указания.

Нет.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Тема второй раз поднимается, в первый я и не понял в чём подвох )))

Green
Offline
Зарегистрирован: 01.10.2015

DetSimen пишет:

Нет.

Лаконично.
- что да?
- тоже нет.

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

Green пишет:
Достаточтно что бы один из операндов был int32_t, даже без явного указания.
Правильно дида говорит - нет! Там принцип-то просто как валенок. Запомните

1. Преобразование производится только тогда, когда реально нужно.

2. Все операции "*" выполняются слева направо.

Вот и всё. Т.е. не просто "один", а первый. Ну, или не первый, но такой, что "до него" никаких неприятностей не произошло.

Green
Offline
Зарегистрирован: 01.10.2015

) Вот вам "простой как валенок" пример:  __delay(8*60*60*33000);
Что там насчёт первого? И "до него никаких неприятностей" - что за выражение?)
 

 

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

Первый - int, второй тоже, перемножается как инт и результат инт. Этот результат умножается на третий (тоже инт) результат - инт), этот результат на четвёртый. Результат опять инт, но это уже неверно -  возникло переполнение. Т.е. в данном примере лонгом может быть дюбой член, но в общем случае - любой, но стоящий ДО переполнения. Вот в этот пример добавьте справа ещё один сомножитель (хоть * 2). И получите, что делать его лонгом бесполезно - ошибка уже появилась до него.

Green
Offline
Зарегистрирован: 01.10.2015

ОК. Все верно. А то я уже начал было сомневаться в теории. Подумал, может уже чего улучшили.)

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

 

А так ?

delay(8L*60L*60L*33000L);

sadman41
Offline
Зарегистрирован: 19.10.2016

Можно просто 8L в первой позиции, но потом константы местами не переставлять.

Sonologist
Sonologist аватар
Offline
Зарегистрирован: 08.06.2018

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

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

если пины в ОДНОМ порту, то их можно зажигать за 2 или 4 (не помню) такта процессора ОДНОВРЕМЕННО.  Зачем - ХЗ. 

SLKH
Offline
Зарегистрирован: 17.08.2015

Sonologist пишет:

И в чем надобность "зажигать" пины абсолютно синхронно?

В вопросе от ТС - ни в чём. Просто он спросил совсем не то, что хотел.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

DetSimen пишет:

если пины в ОДНОМ порту, то их можно зажигать за 2 или 4 (не помню) такта процессора ОДНОВРЕМЕННО.  Зачем - ХЗ. 

что-то многовато, по идее должно за такт

-NMi-
Offline
Зарегистрирован: 20.08.2018

CLR R0 - 1 такт

OUT PORTB,R0 - 1 такт

SER R0 - 1 такт

OUT PORTB,R0 - 1 такт

Итого 4 такта чтоб "дрыгануть" весь порт целиком.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

-NMi- пишет:

CLR R0 - 1 такт

OUT PORTB,R0 - 1 такт

SER R0 - 1 такт

OUT PORTB,R0 - 1 такт

Итого 4 такта чтоб "дрыгануть" весь порт целиком.

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

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

блин, с x86 перепутал.  да. ты прав, NMi.

FF_Group
Offline
Зарегистрирован: 13.12.2015

SLKH пишет:

Sonologist пишет:

И в чем надобность "зажигать" пины абсолютно синхронно?

В вопросе от ТС - ни в чём. Просто он спросил совсем не то, что хотел.

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

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

мне нужно ежедневно в 8 утра и 6 вечера включать "единовременно" (не абсолютно синхронно, и даже не обязательно одновременно) 10 пинов но на разное время работы реле.

Реле в системе только одно, и переключается разьемом "мама" для финишной подстройки работы шнека.

 

-NMi-
Offline
Зарегистрирован: 20.08.2018

ua6em пишет:

и вопрос, без нуления данных и вывода -напрямую, незначащие биты не сбросятся?

Сбросятся.

Тут два варианта:

SBI или CBI - это побитно с портом.

Либо применить маску с прочитанного с порта, AND или OR в зависимости от "сбросить" или "выставить"

Третий вариант (опционально) --- XOR с маской, так мы "передёргиваем" бит или биты, естественно по маске, в порту (8 бит)

Ваащпе вариантов можно накрапать много... всё зависит от "полёта" мысли :))

-NMi-
Offline
Зарегистрирован: 20.08.2018

FF_Group пишет:

1 - Хотел узнать, можно ли записать одной строкой несколько пинов. я так понимаю нельзя, а жаль.

2 - 10 пинов но на разное время работы реле.

1 - можно и одной командой.

2 - можно, но несколькими командами (не более 15-ти команд ASM)

Как? Элементарно...     Стакан ---> Деду, закусь ---> мне     :))

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

-NMi- пишет:

2 - можно, но несколькими командами (не более 15-ти команд ASM)

Как? Элементарно...     Стакан ---> Деду, закусь ---> мне     :))

Но здесь только две команды! А где остальные 13? Мож на них там и мне чего перепадёт?

-NMi-
Offline
Зарегистрирован: 20.08.2018

DetSimen пишет:

если пины в ОДНОМ порту, то их можно зажигать за 2 или 4 (не помню) такта процессора ОДНОВРЕМЕННО. 

А ежли "накатить" стакан-другой, то можно придумать способ и одновременно и не в одном а в нескольких портах (правда не все камни это держут) одновременно. Читаем датащи, фканце, описание портов проца.  :))

-NMi-
Offline
Зарегистрирован: 20.08.2018

ЕвгенийП пишет:

Но здесь только две команды! А где остальные 13? Мож на них там и мне чего перепадёт?

Умом процессор не понять, пока не выпито 0,5   ... попЫтки глубже понимать уже подразумевают ЛИТР!!!

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

FF_Group пишет:

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

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

Цитата:

мне нужно ежедневно в 8 утра и 6 вечера включать "единовременно" (не абсолютно синхронно, и даже не обязательно одновременно) 10 пинов но на разное время работы реле.

Реле в системе только одно, и переключается разьемом "мама" для финишной подстройки работы шнека.

 

Не могу понять, что означает "10 пинов но на разное время работы реле" и причем здесь мама и шнек?

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015
01#pragma pack(push,1)
02typedef struct
03{
04 uint8_t pin;
05 uint16_t workTimeInSeconds;
06 uint32_t startedAt;
07 
08} WorkSetting;
09#pragma pack(pop)
10 
11WorkSetting WorkSettings[] = {
12 
13    {2, 10, 0},
14    {3, 20, 0},
15    {4, 30, 0},
16    {5, 15, 0},
17    {6, 20, 0},
18    {7, 30, 0},
19    {8, 60, 0},
20    {9, 44, 0},
21    {10, 99, 0},
22    {11, 120, 0},
23 
24};
25 
26void setup()
27{
28    const size_t cnt = sizeof(WorkSettings)/sizeof(WorkSettings[0]);
29    for(size_t i=0;i<cnt;i++)
30    {
31        pinMode(WorkSettings[i].pin,OUTPUT);
32    }
33}
34 
35void loop()
36{
37    const size_t cnt = sizeof(WorkSettings)/sizeof(WorkSettings[0]);
38 
39    if(время_8_утра или время_6_вечера)
40    {
41         
42        for(size_t i=0;i<cnt;i++)
43        {
44            if(WorkSettings[i].startedAt == 0)
45            {
46                digitalWrite(WorkSettings[i].pin,HIGH);
47                WorkSettings[i].startedAt = millis();
48            }
49        }      
50    }
51 
52    uint32_t now = millis();
53 
54    for(size_t i=0;i<cnt;i++)
55    {
56        if(WorkSettings[i].startedAt > 0)
57        {
58            uint32_t interval = 1000UL * WorkSettings[i].workTimeInSeconds;
59            if(now - WorkSettings[i].startedAt > interval)
60            {
61                WorkSettings[i].startedAt = 0;
62                digitalWrite(WorkSettings[i].pin,LOW);
63            }
64        }
65    }
66}
FF_Group
Offline
Зарегистрирован: 13.12.2015

asam пишет:

Не могу понять, что означает "10 пинов но на разное время работы реле" и причем здесь мама и шнек?

Ардуино управляет всего лишь одним приводом шнека через реле.
Опытным путем установлено что за 60 секунд шнек нагружает необходимую массу "материала". Но поскольку поставщик материала может измениться изменится насыпная плотность и нужно будет заставить шнек работать 55 или 65 секунд. И что бы каждый раз не лезть в скетч нужно что бы все пины были настроены на разную продолжительность работы, но включались примерно в 8 утра и 18 вечера.
То есть беру просто управляющий провод от реле и переключаю на соседний пин и время подачи материала сокоащается или увеличивается.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

FF_Group][quote=asam пишет:

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

как всё запущено...а две кнопки управления временем не достаточно?

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

FF_Group пишет:
Ардуино управляет всего лишь одним приводом шнека через реле. Опытным путем установлено что за 60 секунд шнек нагружает необходимую массу "материала". Но поскольку поставщик материала может измениться изменится насыпная плотность и нужно будет заставить шнек работать 55 или 65 секунд. И что бы каждый раз не лезть в скетч нужно что бы все пины были настроены на разную продолжительность работы, но включались примерно в 8 утра и 18 вечера. То есть беру просто управляющий провод от реле и переключаю на соседний пин и время подачи материала сокоащается или увеличивается.

Гораздо проще подключить переменное сопротивление на аналоговый вход. и в зависимости от его положения модифицировать время работы шнека. 

-NMi-
Offline
Зарегистрирован: 20.08.2018

FF_Group пишет:

Опытным путем установлено что за 60 секунд шнек нагружает необходимую массу "материала". Но поскольку поставщик материала может измениться изменится насыпная плотность и нужно будет заставить шнек работать 55 или 65 секунд. И что бы каждый раз не лезть в скетч нужно что бы все пины были настроены на разную продолжительность работы, но включались примерно в 8 утра и 18 вечера.

Ну дык паставь RTC и LCD и клавиатуру и сделай меню да и управляй ты хоть часами, хоть секундами... да хоть чем. Неужели для тебя это так трудно???

sadman41
Offline
Зарегистрирован: 19.10.2016

Обычный галетник для выбора входа, который будет определять время работы: D2 - 45 сек, D3 - 50 секунд и т.д.

FF_Group
Offline
Зарегистрирован: 13.12.2015

Трудно... И кнопки трудно, уж молчу про ЛСД с меню
Но ЛСД с меню конечно самый крутой вариант

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

Не, ну если ЛСД, то оно, конечно тяжело. Да и недёшево.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

с ЛСД еще и глючно.