Упрощение кода

abramonromka
Offline
Зарегистрирован: 17.03.2020
Добрый день, форумчане. У меня такая задача: необходимо создать несколько устройств на МК, датчике вибрации/наклона, светодиоде и батарейке (таблетка). Каждое должно светиться по своему. Написал код для МК ATTiny13 (может найду что на замену, но пока она подходит больше всего). Задача всех устройств после удара или движения - светодиод начинает моргать, как только устройство вернули в состояние покоя (положили на стол, например) светодиод поморгал ещё 5 секунд и выключился. Начнёт моргать опять только когда устройство снова приведут в движение (возьмут в руки, ударят, кинут).
 
Пробное устройство я уже собрал, (пульсирующий) всё работает исправно, но память ATTiny13 1Кб, этот код вышел на 564 б, соответственно если я захочу его усложнить, то 1 Кб может не хватить. А так же МК потребляет повышенный ток постоянно. 
 
Собственно прошу Вас помочь упростить код (если это возможно) и, что самое главное, помочь с режимами МК, чтобы увеличить время работы от батарейки. 
 
Заранее Вас благодарю!
 
int vib = 4;
int led = 0;
long loopTime = 5000;

void setup() {
    pinMode(led, OUTPUT);
    pinMode(vib, INPUT);
}

void loop()
{
    if (digitalRead(vib)){
        unsigned long currentMillis = millis();
        while(millis()-currentMillis<=loopTime) {
            for(int fadeValue = 0; fadeValue <=255; fadeValue+=5) {
                 analogWrite(led,fadeValue);
                 delay(2);
            }
            for(int fadeValue = 255; fadeValue >=0; fadeValue-=5) {
                 analogWrite(led,fadeValue);
                 delay(2);
            }
            for(int fadeValue = 0; fadeValue <=255; fadeValue+=5) {
                  analogWrite(led,fadeValue);
                  delay(2);
             }
             for(int fadeValue = 255; fadeValue >=0; fadeValue-=5) {
                  analogWrite(led,fadeValue);
                  delay(2);
             }
             digitalWrite(led, LOW);
             delay(600);
        }
    }
}

 

rkit
Offline
Зарегистрирован: 23.11.2016

Оптимизировать раньше времени не надо. Сначала сделай, потом уже будет ясно, нужно или нет.

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

начните с того, что у вас куча переменных типа int, хотя для одной можно было обойтись байтом, а для остальных - и просто define

Ну и четыре одинаковых цикла for - это ламерство

rkit
Offline
Зарегистрирован: 23.11.2016

b707 пишет:

начните с того, что у вас куча переменных типа int, хотя для одной можно было обойтись байтом, а для остальных - и просто define

Ну и четыре одинаковых цикла for - это ламерство

Это сэкономит 15 байт. Память жрет ядро ардуино. Раньше времени переписывать всё на регистры не надо, особенно если выяснится, что понадобятся библиотеки, которые всё равно используют этот код.

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

Не проще ли взять 85-ую и не трахаться?

Режим МК для уменьшения потребления - SLEEP_MODE_PWR_DOWN

Вот, лучшее руководство по экономии из тех, что видел - http://www.gammon.com.au/forum/?id=11497

 

abramonromka
Offline
Зарегистрирован: 17.03.2020

b707 пишет:

начните с того, что у вас куча переменных типа int, хотя для одной можно было обойтись байтом, а для остальных - и просто define

Ну и четыре одинаковых цикла for - это ламерство

Пока что это для меня не так просто) Поэтому воспользуюсь советом ,если начнет поджимать место rkit, начну углубляться в дебри. Но за совет всё равно большое спасибо! 

abramonromka
Offline
Зарегистрирован: 17.03.2020

rkit пишет:

Оптимизировать раньше времени не надо. Сначала сделай, потом уже будет ясно, нужно или нет.

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

abramonromka
Offline
Зарегистрирован: 17.03.2020

85 дороже. мне бы максимально удешевить проект. 

А вот за ссылку просто респектище, спасибо большое, очень доступный мануал по энергосбережению! 

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

abramonromka пишет:

85 дороже. мне бы максимально удешевить проект. 

Интересно, в какую сумму Вы оцениваете час своей работы?

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

Если "да", можно предположить, что Вы пытаетесь получить бесплатный совет по коммерческому проекту, что на форуме явно не приветствуется.

abramonromka
Offline
Зарегистрирован: 17.03.2020

Нет) В свете последних событий с вирусами, падением рубля и т.д. сейчас стараешься даже рублик сэкономить. Тем более все МК напрямую зависят от пресловутого $. Поэтому и ищу, что подешевле. Время конечно тоже ценно, но оно сейчас есть, а денег, увы нет.

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

abramonromka пишет:
ищу, что подешевле

ATtiny13

ATtiny85

Даёшь экономию рублика!

Kakmyc
Offline
Зарегистрирован: 15.01.2018

#include <avr/io.h>
#include <util/delay.h>
int main(){
    DDRB|=1<<PB5;
    for(;;){
        _delay_ms(500);
        PORTB^=1<<PB5;
    }
}

А какой самый компактный блинк можно написать в среде Arduino IDE ?

У меня меньше не получается.

Если только изменить удобство настройки времени

Kakmyc
Offline
Зарегистрирован: 15.01.2018

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

abramonromka пишет:
ищу, что подешевле

ATtiny13

ATtiny85

Даёшь экономию рублика!

 

У дяди Ляо совсем другие цены

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

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

И побрутальней штоп было - сделать goto вместо for() ;)

Kakmyc
Offline
Зарегистрирован: 15.01.2018

sadman41 пишет:
Если заменить PORTB на PINB и убрать xor, то выйдет немного покороче. И побрутальней штоп было - сделать goto вместо for() ;)

 

Это как ?

PINB , это регистр чтения, в него же нельзя ничего писать.

Применение goto выигрыша никакого не даёт

 

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

Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn. Note that the SBI instruction can be used to toggle one single bit in a port.

А goto для брутальность, а не для эффективности.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

sadman41 пишет:
Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn. Note that the SBI instruction can be used to toggle one single bit in a port. А goto для брутальность, а не для эффективности.

 

Судя по схеме из даташита , это в корне неправильный подход

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

ATmega328P
8-bit AVR Microcontroller with 32K Bytes In-System Programmable Flash
DATASHEET

13.2.2 Toggling the Pin
...

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

Kakmyc пишет:

PINB , это регистр чтения, в него же нельзя ничего писать.

Это лохам нельзя, а мы же с Вами нормальные пацаны!

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Ну тады давайте учите лоха, как это реализовать через PINB без xor , который аж 6 байтов жрёт.

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

Kakmyc пишет:

У дяди Ляо совсем другие цены

Нипатриатична!

И вот как с такими нипатриотами отечественную экономику развивать?

Kakmyc
Offline
Зарегистрирован: 15.01.2018

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

Kakmyc пишет:

У дяди Ляо совсем другие цены

Нипатриатична!

И вот как с такими нипатриотами отечественную экономику развивать?

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

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

Kakmyc пишет:
Ну тады давайте учите лоха, как это реализовать через PINB без xor , который аж 6 байтов жрёт.

Какого лоха? Я ж сказал, что "мы с Вами - нормальные пацаны" :-)

А так, нафига там xor для блинка-то? Там всё, что нужно - единицу запихать. Нужно, например PB0, так и пишете PINB = 1; и никаких ксоров.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Так туда же потом нужно будет ещё 0 писать, а это уже нифига не экономия.

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

Вы б лучше уточнили задачу.

1. "самый компактный блинк" по исходному коду или по объёму памяти?

2. Обязателен ли меандр или можно с любой скважностью?

3. То, что блинк должен быть видимым без осциллографа я понимаю, а ещё какие-то ограничения на частоту есть? Или божно любую разумную ("разумная" == чтобы мигание видеть невооружённым глазом и не ждать час пока мигнёт)

Уточните, может и я поучаствую.

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

Kakmyc пишет:
Так туда же потом нужно будет ещё 0 писать, а это уже нифига не экономия.
Зачем туда 0 писать? От писания туда нуля ничего не происходит. Пин инвертируется при писании единицы.

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

Кактус, я же привёл параграф из даташита, который называется "Toggling the Pin"

#include <avr/io.h>
#include <util/delay.h>
int main() {
  DDRB |= 1 << PB5;
  for (;;) {
    _delay_ms(500);
    PINB = 1 << PB5;
  }
}

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Ппц вот это я затупил.

Только сейчас понял о чём речь.

Да, такая конструкция занимает 156 байт памяти.

Что на 6 байт короче

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

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

Вы б лучше уточнили задачу.

1. "самый компактный блинк" по исходному коду или по объёму памяти?

2. Обязателен ли меандр или можно с любой скважностью?

3. То, что блинк должен быть видимым без осциллографа я понимаю, а ещё какие-то ограничения на частоту есть? Или божно любую разумную ("разумная" == чтобы мигание видеть невооружённым глазом и не ждать час пока мигнёт)

Уточните, может и я поучаствую.

Опять фокусы с таймерами? ;)

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

Я задал вопрос ТС. А то он сначала "компактный", а потом какие-то байты считает. пусть определится что означает компактный, а тогда и посмотрим какие фокусы использовать.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

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

Вы б лучше уточнили задачу.

1. "самый компактный блинк" по исходному коду или по объёму памяти?

2. Обязателен ли меандр или можно с любой скважностью?

3. То, что блинк должен быть видимым без осциллографа я понимаю, а ещё какие-то ограничения на частоту есть? Или божно любую разумную ("разумная" == чтобы мигание видеть невооружённым глазом и не ждать час пока мигнёт)

Уточните, может и я поучаствую.

В данном случае по объему памяти.
Т.к. изначально речь в топике идёт о худых МК.

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

А скважность и частота любые?

Kakmyc
Offline
Зарегистрирован: 15.01.2018

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

А скважность и частота любые?

Ну по аналогии со стандартным блинком .
0.5-1 сек.
При чём желательно, чтоб задавать значение в миллисекундах а не тиках процессора

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

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

Kakmyc
Offline
Зарегистрирован: 15.01.2018

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

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

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

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

Тогда не ставьте таких жёстких условий.

Мигать-так мигать, а то Вам ещё и частоту менять хочется. Может, через Интернет? Зачем блинку что-то менять?

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

Короче, )

#include <avr/io.h>
#include <util/delay.h>
int main() {
  PINB = DDRB = 1<<PB5;
}

 

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

Green пишет:

Короче, )

#include <avr/io.h>
#include <util/delay.h>
int main() {
  PINB = DDRB = 1<<PB5;
}

 

Только не мигает :-(

А вот действительно, реально мигает на 11-ом пине и тоже короче, чем действующий чемпион.

int main (void) {
   while((WDTCSR = PINB = DDRB = 8));
}

Ваш ход. Сокращайте!

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

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

#pragma GCC optimize ("O0")

Мой вариант, к сожалению, с этой опцией не компилируется, а почему - башка не соображает от короновируса.

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

sadman41 пишет:

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

Не согласен. По условию задачи было "в Arduino IDE".  IDE - система для беременных доярок, а не для специалистов по оптимизации, а потому меряться надо результатами на Arduino IDE "из коробки". Можно согласовать версию.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Нихрена себе! Вариант Петровича - 144 байта

а вот такой вариант

int main (void) {
   WDTCSR = PINB = DDRB = 8;
}

тоже отлично мигает, но ... 148 байтов!

Это ваще как? Я ж цикл выбросил!

Нечестный, сцуко!

Green
Offline
Зарегистрирован: 01.10.2015
int main() {
  while (DDRB = PINB = 1<<PB5);
}
Скетч использует 140 байт (0%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 0 байт (0%) динамической памяти, оставляя 2048 байт для локальных переменных. Максимум: 2048 байт.
 

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Green пишет:

int main() {
  while (DDRB = PINB = 1<<PB5);
}
Скетч использует 140 байт (0%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 0 байт (0%) динамической памяти, оставляя 2048 байт для локальных переменных. Максимум: 2048 байт.
 

 

Какой то сомнительный блинк , с точки зрения наблюдателя , просто горящий диод

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

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

Можно согласовать версию.

На этом тоже можно сойтись, в принципе.

abramonromka
Offline
Зарегистрирован: 17.03.2020
Kakmyc
Offline
Зарегистрирован: 15.01.2018
int main() { 
    for(uint16_t a=0;a<65635;a++){};
    PINB|=1<<PB5;
}

Моя версия 134 байт

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

Green пишет:

int main() {
  while (DDRB = PINB = 1<<PB5);
}

Глобальные переменные используют 0 байт (0%) динамической памяти, оставляя 2048 байт для локальных переменных. Максимум: 2048 байт.

Да, только он не мигает, я же Вам уже говорил. Запустите и убедитесь.

Я даже не поленился осциллографом глянуть - он именно не мигает, а не "мигает, но быстро".

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

Kakmyc пишет:

int main() { 
    for(uint16_t a=0;a<65635;a++){};
    PINB|=1<<PB5;
}

Моя версия 134 байт

Тоже не мигает.

Мужики, давайте проверять, прежде, чем выкладывать!

Kakmyc
Offline
Зарегистрирован: 15.01.2018

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

Kakmyc пишет:

int main() { 
    for(uint16_t a=0;a<65635;a++){};
    PINB|=1<<PB5;
}

Моя версия 134 байт

Тоже не мигает.

Мужики, давайте проверять, прежде, чем выкладывать!

 

Там ошибка в коде(очепятка), потому и не мигает.

Значение 65635, следует исправить на 65535, размер становится 140 байт.

 

 

Проверить в моем случае ваще не вариант.монией в сиационаре

Лежу с пее

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

Kakmyc пишет:

Там ошибка в коде(очепятка), потому и не мигает.

Значение 65635, следует исправить на 65535, размер становится 140 байт

Это не единственная ошибка. Порт на вывод Вы не хотите назначить? 

Я же говорю, давайте проверять!

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Вариант с назначением порта 142байта

int main() { 
    DDRB|=1<<PB5;
    for(uint16_t a=0;a<63535;a++){};  
    PINB|=1<<PB5;
}