Помогите оптимизировать
- Войдите на сайт для отправки комментариев
Вс, 26/07/2015 - 10:29
Пишу автополивалку для растения, на данный момент имеется такой скетч
//Pin connected to ST_CP of 74HC595
#define latchPin 1
//Pin connected to SH_CP of 74HC595
#define clockPin 2
////Pin connected to DS of 74HC595
#define dataPin 0
byte dataRED;
byte dataGREEN;
byte dataArrayRED[10];
byte dataArrayGREEN[10];
void setup() {
//set pins to output because they are addressed in the main loop
pinMode(latchPin, OUTPUT);
dataArrayRED[0] = 0x3F; //num 0 00111111
dataArrayRED[1] = 0x06; //num 1 00000110
dataArrayRED[2] = 0x5B; //num 2 01011011
dataArrayRED[3] = 0x4F; //num 3 01001111
dataArrayRED[4] = 0x66; //num 4 01100110
dataArrayRED[5] = 0x6D; //num 5 01101101
dataArrayRED[6] = 0x7D; //num 6 01111101
dataArrayRED[7] = 0x07; //num 7 00000111
dataArrayRED[8] = 0x7F; //num 8 01111111
dataArrayRED[9] = 0x67; //num 9 01100111
dataArrayGREEN[0] = 0x3F; //num 0 00111111
dataArrayGREEN[1] = 0x06; //num 1 00000110
dataArrayGREEN[2] = 0x5B; //num 2 01011011
dataArrayGREEN[3] = 0x4F; //num 3 01001111
dataArrayGREEN[4] = 0x66; //num 4 01100110
dataArrayGREEN[5] = 0x6D; //num 5 01101101
dataArrayGREEN[6] = 0x7D; //num 6 01111101
dataArrayGREEN[7] = 0x07; //num 7 00000111
dataArrayGREEN[8] = 0x7F; //num 8 01111111
dataArrayGREEN[9] = 0x67; //num 9 01100111
}
void loop() {
int y = analogRead(3);
y = constrain(y, 10, 990);
y = y/10;
Chislo(y);
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, dataGREEN);
shiftOut(dataPin, clockPin, dataRED);
digitalWrite(latchPin, 1);
}
void Chislo(int n){
int arr[2] = {n/10, n%10};
if (arr[0] == 1){
dataRED = dataArrayRED[1];
}
else if(arr[0] == 2){
dataRED = dataArrayRED[2];
}
else if(arr[0] == 3){
dataRED = dataArrayRED[3];
}
else if(arr[0] == 4){
dataRED = dataArrayRED[4];
}
else if(arr[0] == 5){
dataRED = dataArrayRED[5];
}
else if(arr[0] == 6){
dataRED = dataArrayRED[6];
}
else if(arr[0] == 7){
dataRED = dataArrayRED[7];
}
else if(arr[0] == 8){
dataRED = dataArrayRED[8];
}
else if(arr[0] == 9){
dataRED = dataArrayRED[9];
}
else if(arr[0] == 0){
dataRED = dataArrayRED[0];
}
if (arr[1] == 1){
dataRED = dataArrayRED[1];
}
else if(arr[1] == 2){
dataGREEN = dataArrayGREEN[2];
}
else if(arr[1] == 3){
dataGREEN = dataArrayGREEN[3];
}
else if(arr[1] == 4){
dataGREEN = dataArrayGREEN[4];
}
else if(arr[1] == 5){
dataGREEN = dataArrayGREEN[5];
}
else if(arr[1] == 6){
dataGREEN = dataArrayGREEN[6];
}
else if(arr[1] == 7){
dataGREEN = dataArrayGREEN[7];
}
else if(arr[1] == 8){
dataGREEN = dataArrayGREEN[8];
}
else if(arr[1] == 9){
dataGREEN = dataArrayGREEN[9];
}
else if(arr[1] == 0){
dataGREEN = dataArrayGREEN[0];
}
}
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
int i=0;
int pinState;
pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, OUTPUT);
digitalWrite(myDataPin, 0);
digitalWrite(myClockPin, 0);
for (i=7; i>=0; i--) {
digitalWrite(myClockPin, 0);
if ( myDataOut & (1<<i) ) {
pinState= 1;
}
else {
pinState= 0;
}
digitalWrite(myDataPin, pinState);
digitalWrite(myClockPin, 1);
digitalWrite(myDataPin, 0);
}
//stop shifting
digitalWrite(myClockPin, 0);
}
В качестве камня используется ATTiny13. Также используется 2 регистра 74HC595. Какие моменты в коде можно улучшить, а то я пока не очень силён в программировании
Для начала так:
//Pin connected to ST_CP of 74HC595 #define latchPin 1 //Pin connected to SH_CP of 74HC595 #define clockPin 2 ////Pin connected to DS of 74HC595 #define dataPin 0 uint8_t oldValue; byte dataFont[10] = { 0x3F, //num 0 00111111 0x06, //num 1 00000110 0x5B, //num 2 01011011 0x4F, //num 3 01001111 0x66, //num 4 01100110 0x6D, //num 5 01101101 0x7D, //num 6 01111101 0x07, //num 7 00000111 0x7F, //num 8 01111111 0x67 //num 9 01100111 }; void setup() { //set pins to output because they are addressed in the main loop pinMode(latchPin, OUTPUT); digitalWrite(latchPin, 1); } void loop() { uint8_t y = constrain(analogRead(3), 1, 99); if(oldValue != y){ oldValue = y; display(y); } } void display(uint8_t n){ shiftOut(dataPin, clockPin, dataFont[n/10]); shiftOut(dataPin, clockPin, dataFont[n%10]); digitalWrite(latchPin, 0); digitalWrite(latchPin, 1); } void shiftOut(uint8_t myDataPin, uint8_t myClockPin, byte myDataOut) { uint8_t i=0; uint8_t pinState; pinMode(myClockPin, OUTPUT); pinMode(myDataPin, OUTPUT); digitalWrite(myDataPin, 0); digitalWrite(myClockPin, 0); for (i=7; i>=0; i--) { digitalWrite(myClockPin, 0); if ( myDataOut & (1<<i) ) { pinState= 1; } else { pinState= 0; } digitalWrite(myDataPin, pinState); digitalWrite(myClockPin, 1); } //stop shifting digitalWrite(myClockPin, 0); }Потом shiftOut Заменить на SPI.transfer() при этои clockpin это SCK, а datapin это MOSI пин из аппаратного интерфейса SPI
#include <SPI.h> //Pin connected to ST_CP of 74HC595 #define latchPin 1 //Pin SH_CP of 74HC595 to SPI SCK //Pin DS of 74HC595 to SPI MOSI uint8_t oldValue; byte dataFont[10] = { 0x3F, //num 0 00111111 0x06, //num 1 00000110 0x5B, //num 2 01011011 0x4F, //num 3 01001111 0x66, //num 4 01100110 0x6D, //num 5 01101101 0x7D, //num 6 01111101 0x07, //num 7 00000111 0x7F, //num 8 01111111 0x67 //num 9 01100111}; void setup() { SPI.begin(); //set pins to output because they are addressed in the main loop pinMode(latchPin, OUTPUT); digitalWrite(latchPin, 1); } void loop() { uint8_t y = constrain(analogRead(3), 1, 99); if(oldValue != y){ oldValue = y; display(y); } } void display(uint8_t n){ SPI.transfer(dataFont[n/10]); SPI.transfer(dataFont[n%10]); digitalWrite(latchPin, 0); digitalWrite(latchPin, 1); }Потом возможно перенести dataFont в PROGMEM - чтобы экономить оперативку. И если переменная имеет значения 0..254 то тип лучше uint8_t - сэкономит память.
Если все замечательно работает и все устраивает, зачем еще оптимизировать? Или оптимизация ради оптимизации?
память чуть ли под конец не забилась
Пишу автополивалку для растения, на данный момент имеется такой скетч
//Pin connected to ST_CP of 74HC595 #define latchPin 1 //Pin connected to SH_CP of 74HC595 #define clockPin 2 ////Pin connected to DS of 74HC595 #define dataPin 0 byte dataRED; byte dataGREEN; byte dataArrayRED[10]; byte dataArrayGREEN[10]; void setup() { //set pins to output because they are addressed in the main loop pinMode(latchPin, OUTPUT); dataArrayRED[0] = 0x3F; //num 0 00111111 dataArrayRED[1] = 0x06; //num 1 00000110 dataArrayRED[2] = 0x5B; //num 2 01011011 dataArrayRED[3] = 0x4F; //num 3 01001111 dataArrayRED[4] = 0x66; //num 4 01100110 dataArrayRED[5] = 0x6D; //num 5 01101101 dataArrayRED[6] = 0x7D; //num 6 01111101 dataArrayRED[7] = 0x07; //num 7 00000111 dataArrayRED[8] = 0x7F; //num 8 01111111 dataArrayRED[9] = 0x67; //num 9 01100111 dataArrayGREEN[0] = 0x3F; //num 0 00111111 dataArrayGREEN[1] = 0x06; //num 1 00000110 dataArrayGREEN[2] = 0x5B; //num 2 01011011 dataArrayGREEN[3] = 0x4F; //num 3 01001111 dataArrayGREEN[4] = 0x66; //num 4 01100110 dataArrayGREEN[5] = 0x6D; //num 5 01101101 dataArrayGREEN[6] = 0x7D; //num 6 01111101 dataArrayGREEN[7] = 0x07; //num 7 00000111 dataArrayGREEN[8] = 0x7F; //num 8 01111111 dataArrayGREEN[9] = 0x67; //num 9 01100111 } void loop() { int y = analogRead(3); y = constrain(y, 10, 990); y = y/10; Chislo(y); digitalWrite(latchPin, 0); shiftOut(dataPin, clockPin, dataGREEN); shiftOut(dataPin, clockPin, dataRED); digitalWrite(latchPin, 1); } void Chislo(int n){ int arr[2] = {n/10, n%10}; if (arr[0] == 1){ dataRED = dataArrayRED[1]; } else if(arr[0] == 2){ dataRED = dataArrayRED[2]; } else if(arr[0] == 3){ dataRED = dataArrayRED[3]; } else if(arr[0] == 4){ dataRED = dataArrayRED[4]; } else if(arr[0] == 5){ dataRED = dataArrayRED[5]; } else if(arr[0] == 6){ dataRED = dataArrayRED[6]; } else if(arr[0] == 7){ dataRED = dataArrayRED[7]; } else if(arr[0] == 8){ dataRED = dataArrayRED[8]; } else if(arr[0] == 9){ dataRED = dataArrayRED[9]; } else if(arr[0] == 0){ dataRED = dataArrayRED[0]; } if (arr[1] == 1){ dataRED = dataArrayRED[1]; } else if(arr[1] == 2){ dataGREEN = dataArrayGREEN[2]; } else if(arr[1] == 3){ dataGREEN = dataArrayGREEN[3]; } else if(arr[1] == 4){ dataGREEN = dataArrayGREEN[4]; } else if(arr[1] == 5){ dataGREEN = dataArrayGREEN[5]; } else if(arr[1] == 6){ dataGREEN = dataArrayGREEN[6]; } else if(arr[1] == 7){ dataGREEN = dataArrayGREEN[7]; } else if(arr[1] == 8){ dataGREEN = dataArrayGREEN[8]; } else if(arr[1] == 9){ dataGREEN = dataArrayGREEN[9]; } else if(arr[1] == 0){ dataGREEN = dataArrayGREEN[0]; } } void shiftOut(int myDataPin, int myClockPin, byte myDataOut) { int i=0; int pinState; pinMode(myClockPin, OUTPUT); pinMode(myDataPin, OUTPUT); digitalWrite(myDataPin, 0); digitalWrite(myClockPin, 0); for (i=7; i>=0; i--) { digitalWrite(myClockPin, 0); if ( myDataOut & (1<<i) ) { pinState= 1; } else { pinState= 0; } digitalWrite(myDataPin, pinState); digitalWrite(myClockPin, 1); digitalWrite(myDataPin, 0); } //stop shifting digitalWrite(myClockPin, 0); }В качестве камня используется ATTiny13. Также используется 2 регистра 74HC595. Какие моменты в коде можно улучшить, а то я пока не очень силён в программировании
А как и чем прошивали AtTiny чтобы залить данный скетч??? Может есть схема устройства с обсвязкой МКAttiny + резисторы, кондеры и прочее? Хочу сам просто уйти от ардуино uno на более дешевый вариант.
Программатором MiniPro TL866CS. Так вам вроде даже можно прошивать тиньку через сам ардуино.
Apocalyps, у человека нет 300руб на Uno, а вы ему программатор за 2500 предлагаете :)
Вообщем чтобы новых тем не заводить, возникла такая проблема. Если значение переменной "y" больше 45, то начинает некоректно работать код, перестают выводится символы. Вся проблема в if конструкции, где написано "Выполнение полива"
//Пин подключенный к ST_CP на 74HC595 #define latchPin 1 //Пин подключенный к SH_CP на 74HC595 #define clockPin 2 //Пин подключенный к DS на 74HC595 #define dataPin 0 byte dataRED, dataGREEN; //значения на вывод byte dataArrayRED[10], dataArrayGREEN[10]; //описание сегментов void setup() { pinMode(latchPin, OUTPUT); pinMode(4, OUTPUT); dataArrayRED[0] = 0x3F; //num 0 00111111 dataArrayRED[1] = 0x06; //num 1 00000110 dataArrayRED[2] = 0x5B; //num 2 01011011 dataArrayRED[3] = 0x4F; //num 3 01001111 dataArrayRED[4] = 0x66; //num 4 01100110 dataArrayRED[5] = 0x6D; //num 5 01101101 dataArrayRED[6] = 0x7D; //num 6 01111101 dataArrayRED[7] = 0x07; //num 7 00000111 dataArrayRED[8] = 0x7F; //num 8 01111111 dataArrayRED[9] = 0x67; //num 9 01100111 dataArrayGREEN[0] = 0x3F; //num 0 00111111 dataArrayGREEN[1] = 0x06; //num 1 00000110 dataArrayGREEN[2] = 0x5B; //num 2 01011011 dataArrayGREEN[3] = 0x4F; //num 3 01001111 dataArrayGREEN[4] = 0x66; //num 4 01100110 dataArrayGREEN[5] = 0x6D; //num 5 01101101 dataArrayGREEN[6] = 0x7D; //num 6 01111101 dataArrayGREEN[7] = 0x07; //num 7 00000111 dataArrayGREEN[8] = 0x7F; //num 8 01111111 dataArrayGREEN[9] = 0x67; //num 9 01100111 } void loop() { int y = analogRead(3); //Сбор данных с АЦП, сопротивление земли y = (constrain(y, 10, 990)) / 10; //Уменьшение диапазона и подготовка к выводу ///// Выполнение полива ///// if (y > 45) { digitalWrite(4, HIGH); delay(5000); digitalWrite(4, LOW); delay(2000); } Chislo(y); digitalWrite(latchPin, 0); shiftOut(dataPin, clockPin, dataGREEN); shiftOut(dataPin, clockPin, dataRED); digitalWrite(latchPin, 1); } ///// Обработка числа на вывод ///// void Chislo(uint8_t n) { uint8_t arr[2] = {n / 10, n % 10}; switch (arr[0]) { case 0: dataRED = dataArrayRED[0]; break; case 1: dataRED = dataArrayRED[1]; break; case 2: dataRED = dataArrayRED[2]; break; case 3: dataRED = dataArrayRED[3]; break; case 4: dataRED = dataArrayRED[4]; break; case 5: dataRED = dataArrayRED[5]; break; case 6: dataRED = dataArrayRED[6]; break; case 7: dataRED = dataArrayRED[7]; break; case 8: dataRED = dataArrayRED[8]; break; case 9: dataRED = dataArrayRED[9]; break; } switch (arr[1]) { case 0: dataGREEN = dataArrayGREEN[0]; break; case 1: dataGREEN = dataArrayGREEN[1]; break; case 2: dataGREEN = dataArrayGREEN[2]; break; case 3: dataGREEN = dataArrayGREEN[3]; break; case 4: dataGREEN = dataArrayGREEN[4]; break; case 5: dataGREEN = dataArrayGREEN[5]; break; case 6: dataGREEN = dataArrayGREEN[6]; break; case 7: dataGREEN = dataArrayGREEN[7]; break; case 8: dataGREEN = dataArrayGREEN[8]; break; case 9: dataGREEN = dataArrayGREEN[9]; break; } } void shiftOut(int myDataPin, int myClockPin, byte myDataOut) { int i = 0; int pinState; pinMode(myClockPin, OUTPUT); pinMode(myDataPin, OUTPUT); digitalWrite(myDataPin, 0); digitalWrite(myClockPin, 0); for (i = 7; i >= 0; i--) { digitalWrite(myClockPin, 0); if ( myDataOut & (1 << i) ) { pinState = 1; } else { pinState = 0; } digitalWrite(myDataPin, pinState); digitalWrite(myClockPin, 1); digitalWrite(myDataPin, 0); } digitalWrite(myClockPin, 0); }Apocalyps, у человека нет 300руб на Uno, а вы ему программатор за 2500 предлагаете :)
я просто подумал, что Uno у него в наличии
Apocalyps, по вопросу -вы как раз столкнулись с тем, почему не советуют использовать delay. Нужно убирать delay ,лучше вынести полив в отдельную функцию, Из loop контролировать в какой стадии находится процесс полива через сравнение millis(). В теме "мигаем без delay" можно посмотреть как решать такую задачу.
dimax, используя алгоритм из той статьи...короче у меня бинарник больше 1024 байт получается :-(
В плане оптимизации предлагаю заменить строки 65-129 кода из сообщения #7 вот чем:
В плане оптимизации предлагаю заменить строки 65-129 кода из сообщения #7 вот чем:
Сейчас просто нет возможности проверить, а что я этими строками изменю? Я смогу отказаться от конструкций case-break?
Именно.
Вы используете switch() для того что бы проверить например будет ли элемент номер 0 равен 0 и если да, то берете элементы номер 0 массивов dataArrayRED[] и dataArrayGREEN[]. И так для всего диапазона этих массивов.
В данном случает такие проверки не нужны, можно сразу подставить значение элемета массива Arr[] в качестве номеров элементов массивов dataArrayRED[] и dataArrayGREEN[].
Так избавляемся от громоздких конструкций switch() заменяя их на эти две строки.
Кроме того, от массива Arr[] тоже можно избавиться, и тогда фунция примет следующий вид:
void Chislo(uint8_t n) { dataRED = dataArrayRED[n/10]; dataGREEN = dataArrayGREEN[n%10]; }И возникает вопрос - а есть ли смысл в этой фунции из двух строк. Если склоняемся к мысли, что смысл есть, то так и оставляем. Если все таки нет и хватит поясняющего комментария, то в функции loop() заменяем вызов функции Chislo(y); на следующее:
Получается, что избавились от громоздкой функции и ее вызова, сократив тем самым объем кода примерно в два раза.
Получается, что избавились от громоздкой функции и ее вызова, сократив тем самым объем кода примерно в два раза.
Замечательно! 202 байта сэкономлено