Картинка для привлечения внимания
На днях появилась подработка, поступил заказ записать скетч на ардуино. Простенький, но объёмный. С повторяющимися блоками. Нужно было управлять каждым портом Arduino Mega отдельно, при получении команды по Uart. Отправляешь символ — и светодиод (к примеру) загорается на определенное время. Написал скетч на 2 команды, скинул заказчику для тестов, получил предоплату. Дальше, нужно было масштабировать на все порты.
Для начала я честно попробовал руками. Написав первые 26 #define, энтузиазм иссяк. Я пошел подышать свежим воздухом, и вспомнил, что у меня на ПК (Win 7 x64), уже установлен Python 3.6 из дистрибутива Anaconda. Кстати, это наиболее удобный способ установки Python`а на Windows, т.к. всё уже включено и настроено по умолчанию, и есть пакетный менеджер.
Итак, приступим.
Создаем папку, в ней пустой файл, я назвал его «arduino_gen.py» и bat файл «start_py.bat» со следующим содержимым:
python.exe arduino_gen.py > code_out.txt
@pause
Этот файл нам потребуется, для запуска программы на Python`е
Теперь мы напишем программку, которая сгенерирует нам необходимый код для Arduino.
Для начала, создадим два списка со всеми необходимыми нам значениями, которые мы будем подставлять в код. Имена могут быть любыми, дело вкуса.
chap = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
num = ['2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53']
И две переменные, для перебора списков
i = 0
k = 0
И теперь создадим цикл для генерации #define PIN_a 2… #define PIN_Z 53
iteration1 = True
while iteration1:
print('#define PIN_' + chap[i] + ' ' + num[k])
i = i + 1
k = k + 1
if i > 51:
iteration1 = False
print()
Сохраняем, запускаем файл «start_py.bat»
#define PIN_a 2
#define PIN_b 3
#define PIN_c 4
#define PIN_d 5
#define PIN_e 6
#define PIN_f 7
#define PIN_g 8
#define PIN_h 9
#define PIN_i 10
#define PIN_j 11
#define PIN_k 12
#define PIN_l 13
#define PIN_m 14
#define PIN_n 15
#define PIN_o 16
#define PIN_p 17
#define PIN_q 18
#define PIN_r 19
#define PIN_s 20
#define PIN_t 21
#define PIN_u 22
#define PIN_v 23
#define PIN_w 24
#define PIN_x 25
#define PIN_y 26
#define PIN_z 27
#define PIN_A 28
#define PIN_B 29
#define PIN_C 30
#define PIN_D 31
#define PIN_E 32
#define PIN_F 33
#define PIN_G 34
#define PIN_H 35
#define PIN_I 36
#define PIN_J 37
#define PIN_K 38
#define PIN_L 39
#define PIN_M 40
#define PIN_N 41
#define PIN_O 42
#define PIN_P 43
#define PIN_Q 44
#define PIN_R 45
#define PIN_S 46
#define PIN_T 47
#define PIN_U 48
#define PIN_V 49
#define PIN_W 50
#define PIN_X 51
#define PIN_Y 52
#define PIN_Z 53
Если мы хотим вывести результат сразу в файл, тогда допишем:
python.exe arduino_gen.py > code_out.txt
@pause
В результате, мы получим файл «code_out.txt » из которого, код удобно копировать в скетч в лучших традициях Arduino.
Уже на этом этапе, у меня возник вопрос, хватит ли у Arduino памяти, если сгенерировать большое количество переменных. Однако, забегая вперед, скажу, что памяти вполне хватило, в чем можно убедиться про компиляции скетча.
Далее, я приведу остальной код, в котором несложно разобраться. Но, для начала, рассмотрим
// Задаем пины
#define PIN_a 2
#define PIN_b 3
//Задаем время
#define TIME_a 10000
#define TIME_b 10000
//логическое состояние светодиода
boolean ledState_a = false;
boolean ledState_b = false;
int time_a = 0;
int time_b = 0;
void setup() {
// инициализация
Serial.begin(9600);
for (int i = 2; i <= 53; i++)
pinMode(i, OUTPUT);
}
void loop() {
if (Serial.available() >0) {
int x = Serial.read();
//a
if(x == 'a'){
ledState_a = true;
time_a = TIME_a;
x = 0;
}
//b
if(x == 'b'){
ledState_b = true;
time_b = TIME_b;
x = 0;
}
}
// Исполнительная часть
//a
if(ledState_a == true){
time_a = time_a - 1;
digitalWrite(PIN_a, HIGH);
}
if(time_a == 0){
ledState_a = false;
}
if(ledState_a == false){
digitalWrite(PIN_a, LOW);
}
//b
if(ledState_b == true){
time_b = time_b - 1;
}
if(time_b > 0){
digitalWrite(PIN_b, HIGH);
}
if(time_b == 0){
digitalWrite(PIN_b, LOW);
ledState_b = false;
}
//Задержка в конце
delay(1);
}
Здесь, нужно сгенерировать 4 блока кода в начале. И два блока в конце. В последствии, заказчик захотел изменить логику работы, чтобы при приходе заглавной буквы менялось состояние выхода. Я переписал участок кода:
//Когда приходит большая буква - меняем состояние
//A
if(x == 'A'){
digitalWrite (PIN_A, !digitalRead(PIN_A));
x = 0;
}
И масштабировал при помощи Python'а
i = 26
iteration7 = True
while iteration7:
print()
print('//' + chap[i])
print("if(x == '" + chap[i] + "'){")
print(' digitalWrite (PIN_' + chap[i] + ', !digitalRead(PIN_' + chap[i] + '));')
print(' x = 0;')
print(' }')
i = i + 1
if i > 51:
iteration7 = False
print()
print('}')
print()
Вот, что в итоге получилось.
#define PIN_a 2
#define PIN_b 3
#define PIN_c 4
#define PIN_d 5
#define PIN_e 6
#define PIN_f 7
#define PIN_g 8
#define PIN_h 9
#define PIN_i 10
#define PIN_j 11
#define PIN_k 12
#define PIN_l 13
#define PIN_m 14
#define PIN_n 15
#define PIN_o 16
#define PIN_p 17
#define PIN_q 18
#define PIN_r 19
#define PIN_s 20
#define PIN_t 21
#define PIN_u 22
#define PIN_v 23
#define PIN_w 24
#define PIN_x 25
#define PIN_y 26
#define PIN_z 27
#define PIN_A 28
#define PIN_B 29
#define PIN_C 30
#define PIN_D 31
#define PIN_E 32
#define PIN_F 33
#define PIN_G 34
#define PIN_H 35
#define PIN_I 36
#define PIN_J 37
#define PIN_K 38
#define PIN_L 39
#define PIN_M 40
#define PIN_N 41
#define PIN_O 42
#define PIN_P 43
#define PIN_Q 44
#define PIN_R 45
#define PIN_S 46
#define PIN_T 47
#define PIN_U 48
#define PIN_V 49
#define PIN_W 50
#define PIN_X 51
#define PIN_Y 52
#define PIN_Z 53
//Задаем время
//Здесь, скорее всего, потребуется поправка
//Например, 1 секунда может быть не 1000, а 865, к примеру.
//Нужно будет секундомером померить, и, если необходимо,
// уменьшить на некий коофициент
#define TIME_a 1000
#define TIME_b 1000
#define TIME_c 1000
#define TIME_d 1000
#define TIME_e 1000
#define TIME_f 1000
#define TIME_g 1000
#define TIME_h 1000
#define TIME_i 1000
#define TIME_j 1000
#define TIME_k 1000
#define TIME_l 1000
#define TIME_m 1000
#define TIME_n 1000
#define TIME_o 1000
#define TIME_p 1000
#define TIME_q 1000
#define TIME_r 1000
#define TIME_s 1000
#define TIME_t 1000
#define TIME_u 1000
#define TIME_v 1000
#define TIME_w 1000
#define TIME_x 1000
#define TIME_y 1000
#define TIME_z 1000
#define TIME_A 1000
#define TIME_B 1000
#define TIME_C 1000
#define TIME_D 1000
#define TIME_E 1000
#define TIME_F 1000
#define TIME_G 1000
#define TIME_H 1000
#define TIME_I 1000
#define TIME_J 1000
#define TIME_K 1000
#define TIME_L 1000
#define TIME_M 1000
#define TIME_N 1000
#define TIME_O 1000
#define TIME_P 1000
#define TIME_Q 1000
#define TIME_R 1000
#define TIME_S 1000
#define TIME_T 1000
#define TIME_U 1000
#define TIME_V 1000
#define TIME_W 1000
#define TIME_X 1000
#define TIME_Y 1000
#define TIME_Z 1000
//логическое состояние светодиода (да / нет)
boolean ledState_a = false;
boolean ledState_b = false;
boolean ledState_c = false;
boolean ledState_d = false;
boolean ledState_e = false;
boolean ledState_f = false;
boolean ledState_g = false;
boolean ledState_h = false;
boolean ledState_i = false;
boolean ledState_j = false;
boolean ledState_k = false;
boolean ledState_l = false;
boolean ledState_m = false;
boolean ledState_n = false;
boolean ledState_o = false;
boolean ledState_p = false;
boolean ledState_q = false;
boolean ledState_r = false;
boolean ledState_s = false;
boolean ledState_t = false;
boolean ledState_u = false;
boolean ledState_v = false;
boolean ledState_w = false;
boolean ledState_x = false;
boolean ledState_y = false;
boolean ledState_z = false;
boolean ledState_A = false;
boolean ledState_B = false;
boolean ledState_C = false;
boolean ledState_D = false;
boolean ledState_E = false;
boolean ledState_F = false;
boolean ledState_G = false;
boolean ledState_H = false;
boolean ledState_I = false;
boolean ledState_J = false;
boolean ledState_K = false;
boolean ledState_L = false;
boolean ledState_M = false;
boolean ledState_N = false;
boolean ledState_O = false;
boolean ledState_P = false;
boolean ledState_Q = false;
boolean ledState_R = false;
boolean ledState_S = false;
boolean ledState_T = false;
boolean ledState_U = false;
boolean ledState_V = false;
boolean ledState_W = false;
boolean ledState_X = false;
boolean ledState_Y = false;
boolean ledState_Z = false;
//Переменные, для хранения времени
int time_a = 0;
int time_b = 0;
int time_c = 0;
int time_d = 0;
int time_e = 0;
int time_f = 0;
int time_g = 0;
int time_h = 0;
int time_i = 0;
int time_j = 0;
int time_k = 0;
int time_l = 0;
int time_m = 0;
int time_n = 0;
int time_o = 0;
int time_p = 0;
int time_q = 0;
int time_r = 0;
int time_s = 0;
int time_t = 0;
int time_u = 0;
int time_v = 0;
int time_w = 0;
int time_x = 0;
int time_y = 0;
int time_z = 0;
int time_A = 0;
int time_B = 0;
int time_C = 0;
int time_D = 0;
int time_E = 0;
int time_F = 0;
int time_G = 0;
int time_H = 0;
int time_I = 0;
int time_J = 0;
int time_K = 0;
int time_L = 0;
int time_M = 0;
int time_N = 0;
int time_O = 0;
int time_P = 0;
int time_Q = 0;
int time_R = 0;
int time_S = 0;
int time_T = 0;
int time_U = 0;
int time_V = 0;
int time_W = 0;
int time_X = 0;
int time_Y = 0;
int time_Z = 0;
void setup() {
// не стал переписывать инициализацию
Serial.begin(9600);
for (int i = 2; i <= 53; i++)
pinMode(i, OUTPUT);
}
void loop() {
if (Serial.available() >0) {
int x = Serial.read();
//Проверяем, что у нас пришло
//a
if(x == 'a'){
ledState_a = true;
time_a = TIME_a;
x = 0;
}
//b
if(x == 'b'){
ledState_b = true;
time_b = TIME_b;
x = 0;
}
//c
if(x == 'c'){
ledState_c = true;
time_c = TIME_c;
x = 0;
}
//d
if(x == 'd'){
ledState_d = true;
time_d = TIME_d;
x = 0;
}
//e
if(x == 'e'){
ledState_e = true;
time_e = TIME_e;
x = 0;
}
//f
if(x == 'f'){
ledState_f = true;
time_f = TIME_f;
x = 0;
}
//g
if(x == 'g'){
ledState_g = true;
time_g = TIME_g;
x = 0;
}
//h
if(x == 'h'){
ledState_h = true;
time_h = TIME_h;
x = 0;
}
//i
if(x == 'i'){
ledState_i = true;
time_i = TIME_i;
x = 0;
}
//j
if(x == 'j'){
ledState_j = true;
time_j = TIME_j;
x = 0;
}
//k
if(x == 'k'){
ledState_k = true;
time_k = TIME_k;
x = 0;
}
//l
if(x == 'l'){
ledState_l = true;
time_l = TIME_l;
x = 0;
}
//m
if(x == 'm'){
ledState_m = true;
time_m = TIME_m;
x = 0;
}
//n
if(x == 'n'){
ledState_n = true;
time_n = TIME_n;
x = 0;
}
//o
if(x == 'o'){
ledState_o = true;
time_o = TIME_o;
x = 0;
}
//p
if(x == 'p'){
ledState_p = true;
time_p = TIME_p;
x = 0;
}
//q
if(x == 'q'){
ledState_q = true;
time_q = TIME_q;
x = 0;
}
//r
if(x == 'r'){
ledState_r = true;
time_r = TIME_r;
x = 0;
}
//s
if(x == 's'){
ledState_s = true;
time_s = TIME_s;
x = 0;
}
//t
if(x == 't'){
ledState_t = true;
time_t = TIME_t;
x = 0;
}
//u
if(x == 'u'){
ledState_u = true;
time_u = TIME_u;
x = 0;
}
//v
if(x == 'v'){
ledState_v = true;
time_v = TIME_v;
x = 0;
}
//w
if(x == 'w'){
ledState_w = true;
time_w = TIME_w;
x = 0;
}
//x
if(x == 'x'){
ledState_x = true;
time_x = TIME_x;
x = 0;
}
//y
if(x == 'y'){
ledState_y = true;
time_y = TIME_y;
x = 0;
}
//z
if(x == 'z'){
ledState_z = true;
time_z = TIME_z;
x = 0;
}
//Когда приходит большая буква — меняем состояние
//A
if(x == 'A'){
digitalWrite (PIN_A, !digitalRead(PIN_A));
x = 0;
}
//B
if(x == 'B'){
digitalWrite (PIN_B, !digitalRead(PIN_B));
x = 0;
}
//C
if(x == 'C'){
digitalWrite (PIN_C, !digitalRead(PIN_C));
x = 0;
}
//D
if(x == 'D'){
digitalWrite (PIN_D, !digitalRead(PIN_D));
x = 0;
}
//E
if(x == 'E'){
digitalWrite (PIN_E, !digitalRead(PIN_E));
x = 0;
}
//F
if(x == 'F'){
digitalWrite (PIN_F, !digitalRead(PIN_F));
x = 0;
}
//G
if(x == 'G'){
digitalWrite (PIN_G, !digitalRead(PIN_G));
x = 0;
}
//H
if(x == 'H'){
digitalWrite (PIN_H, !digitalRead(PIN_H));
x = 0;
}
//I
if(x == 'I'){
digitalWrite (PIN_I, !digitalRead(PIN_I));
x = 0;
}
//J
if(x == 'J'){
digitalWrite (PIN_J, !digitalRead(PIN_J));
x = 0;
}
//K
if(x == 'K'){
digitalWrite (PIN_K, !digitalRead(PIN_K));
x = 0;
}
//L
if(x == 'L'){
digitalWrite (PIN_L, !digitalRead(PIN_L));
x = 0;
}
//M
if(x == 'M'){
digitalWrite (PIN_M, !digitalRead(PIN_M));
x = 0;
}
//N
if(x == 'N'){
digitalWrite (PIN_N, !digitalRead(PIN_N));
x = 0;
}
//O
if(x == 'O'){
digitalWrite (PIN_O, !digitalRead(PIN_O));
x = 0;
}
//P
if(x == 'P'){
digitalWrite (PIN_P, !digitalRead(PIN_P));
x = 0;
}
//Q
if(x == 'Q'){
digitalWrite (PIN_Q, !digitalRead(PIN_Q));
x = 0;
}
//R
if(x == 'R'){
digitalWrite (PIN_R, !digitalRead(PIN_R));
x = 0;
}
//S
if(x == 'S'){
digitalWrite (PIN_S, !digitalRead(PIN_S));
x = 0;
}
//T
if(x == 'T'){
digitalWrite (PIN_T, !digitalRead(PIN_T));
x = 0;
}
//U
if(x == 'U'){
digitalWrite (PIN_U, !digitalRead(PIN_U));
x = 0;
}
//V
if(x == 'V'){
digitalWrite (PIN_V, !digitalRead(PIN_V));
x = 0;
}
//W
if(x == 'W'){
digitalWrite (PIN_W, !digitalRead(PIN_W));
x = 0;
}
//X
if(x == 'X'){
digitalWrite (PIN_X, !digitalRead(PIN_X));
x = 0;
}
//Y
if(x == 'Y'){
digitalWrite (PIN_Y, !digitalRead(PIN_Y));
x = 0;
}
//Z
if(x == 'Z'){
digitalWrite (PIN_Z, !digitalRead(PIN_Z));
x = 0;
}
}
//a
if(ledState_a == true){
time_a = time_a — 1;
digitalWrite(PIN_a, HIGH);
}
if(time_a == 0){
ledState_a = false;
}
if(ledState_a == false){
digitalWrite(PIN_a, LOW);
}
//b
if(ledState_b == true){
time_b = time_b — 1;
digitalWrite(PIN_b, HIGH);
}
if(time_b == 0){
ledState_b = false;
}
if(ledState_b == false){
digitalWrite(PIN_b, LOW);
}
//c
if(ledState_c == true){
time_c = time_c — 1;
digitalWrite(PIN_c, HIGH);
}
if(time_c == 0){
ledState_c = false;
}
if(ledState_c == false){
digitalWrite(PIN_c, LOW);
}
//d
if(ledState_d == true){
time_d = time_d — 1;
digitalWrite(PIN_d, HIGH);
}
if(time_d == 0){
ledState_d = false;
}
if(ledState_d == false){
digitalWrite(PIN_d, LOW);
}
//e
if(ledState_e == true){
time_e = time_e — 1;
digitalWrite(PIN_e, HIGH);
}
if(time_e == 0){
ledState_e = false;
}
if(ledState_e == false){
digitalWrite(PIN_e, LOW);
}
//f
if(ledState_f == true){
time_f = time_f — 1;
digitalWrite(PIN_f, HIGH);
}
if(time_f == 0){
ledState_f = false;
}
if(ledState_f == false){
digitalWrite(PIN_f, LOW);
}
//g
if(ledState_g == true){
time_g = time_g — 1;
digitalWrite(PIN_g, HIGH);
}
if(time_g == 0){
ledState_g = false;
}
if(ledState_g == false){
digitalWrite(PIN_g, LOW);
}
//h
if(ledState_h == true){
time_h = time_h — 1;
digitalWrite(PIN_h, HIGH);
}
if(time_h == 0){
ledState_h = false;
}
if(ledState_h == false){
digitalWrite(PIN_h, LOW);
}
//i
if(ledState_i == true){
time_i = time_i — 1;
digitalWrite(PIN_i, HIGH);
}
if(time_i == 0){
ledState_i = false;
}
if(ledState_i == false){
digitalWrite(PIN_i, LOW);
}
//j
if(ledState_j == true){
time_j = time_j — 1;
digitalWrite(PIN_j, HIGH);
}
if(time_j == 0){
ledState_j = false;
}
if(ledState_j == false){
digitalWrite(PIN_j, LOW);
}
//k
if(ledState_k == true){
time_k = time_k — 1;
digitalWrite(PIN_k, HIGH);
}
if(time_k == 0){
ledState_k = false;
}
if(ledState_k == false){
digitalWrite(PIN_k, LOW);
}
//l
if(ledState_l == true){
time_l = time_l — 1;
digitalWrite(PIN_l, HIGH);
}
if(time_l == 0){
ledState_l = false;
}
if(ledState_l == false){
digitalWrite(PIN_l, LOW);
}
//m
if(ledState_m == true){
time_m = time_m — 1;
digitalWrite(PIN_m, HIGH);
}
if(time_m == 0){
ledState_m = false;
}
if(ledState_m == false){
digitalWrite(PIN_m, LOW);
}
//n
if(ledState_n == true){
time_n = time_n — 1;
digitalWrite(PIN_n, HIGH);
}
if(time_n == 0){
ledState_n = false;
}
if(ledState_n == false){
digitalWrite(PIN_n, LOW);
}
//o
if(ledState_o == true){
time_o = time_o — 1;
digitalWrite(PIN_o, HIGH);
}
if(time_o == 0){
ledState_o = false;
}
if(ledState_o == false){
digitalWrite(PIN_o, LOW);
}
//p
if(ledState_p == true){
time_p = time_p — 1;
digitalWrite(PIN_p, HIGH);
}
if(time_p == 0){
ledState_p = false;
}
if(ledState_p == false){
digitalWrite(PIN_p, LOW);
}
//q
if(ledState_q == true){
time_q = time_q — 1;
digitalWrite(PIN_q, HIGH);
}
if(time_q == 0){
ledState_q = false;
}
if(ledState_q == false){
digitalWrite(PIN_q, LOW);
}
//r
if(ledState_r == true){
time_r = time_r — 1;
digitalWrite(PIN_r, HIGH);
}
if(time_r == 0){
ledState_r = false;
}
if(ledState_r == false){
digitalWrite(PIN_r, LOW);
}
//s
if(ledState_s == true){
time_s = time_s — 1;
digitalWrite(PIN_s, HIGH);
}
if(time_s == 0){
ledState_s = false;
}
if(ledState_s == false){
digitalWrite(PIN_s, LOW);
}
//t
if(ledState_t == true){
time_t = time_t — 1;
digitalWrite(PIN_t, HIGH);
}
if(time_t == 0){
ledState_t = false;
}
if(ledState_t == false){
digitalWrite(PIN_t, LOW);
}
//u
if(ledState_u == true){
time_u = time_u — 1;
digitalWrite(PIN_u, HIGH);
}
if(time_u == 0){
ledState_u = false;
}
if(ledState_u == false){
digitalWrite(PIN_u, LOW);
}
//v
if(ledState_v == true){
time_v = time_v — 1;
digitalWrite(PIN_v, HIGH);
}
if(time_v == 0){
ledState_v = false;
}
if(ledState_v == false){
digitalWrite(PIN_v, LOW);
}
//w
if(ledState_w == true){
time_w = time_w — 1;
digitalWrite(PIN_w, HIGH);
}
if(time_w == 0){
ledState_w = false;
}
if(ledState_w == false){
digitalWrite(PIN_w, LOW);
}
//x
if(ledState_x == true){
time_x = time_x — 1;
digitalWrite(PIN_x, HIGH);
}
if(time_x == 0){
ledState_x = false;
}
if(ledState_x == false){
digitalWrite(PIN_x, LOW);
}
//y
if(ledState_y == true){
time_y = time_y — 1;
digitalWrite(PIN_y, HIGH);
}
if(time_y == 0){
ledState_y = false;
}
if(ledState_y == false){
digitalWrite(PIN_y, LOW);
}
//z
if(ledState_z == true){
time_z = time_z — 1;
digitalWrite(PIN_z, HIGH);
}
if(time_z == 0){
ledState_z = false;
}
if(ledState_z == false){
digitalWrite(PIN_z, LOW);
}
delay(1);
}
chap = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
num = ['2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53']
i = 0
k = 0
iteration1 = True
while iteration1:
print('#define PIN_' + chap[i] + ' ' + num[k])
i = i + 1
k = k + 1
if i > 51:
iteration1 = False
print()
i = 0
iteration2 = True
while iteration2:
print('#define TIME_' + chap[i] + ' ' + '1000')
i = i + 1
if i > 51:
iteration2 = False
print()
i = 0
iteration3 = True
while iteration3:
print('boolean ledState_' + chap[i] + ' ' + '= false;')
i = i + 1
if i > 51:
iteration3 = False
print()
i = 0
iteration4 = True
while iteration4:
print('int time_' + chap[i] + ' ' + '= 0;')
i = i + 1
if i > 51:
iteration4 = False
i = 0
iteration5 = True
while iteration5:
print()
print('//' + chap[i])
print("if(x == '" + chap[i] + "'){")
print(' ledState_' + chap[i] + ' = true;')
print(' time_' + chap[i] + ' = TIME_' + chap[i] + ';')
print(' x = 0;')
print(' }')
i = i + 1
if i > 51:
iteration5 = False
print()
print('}')
print()
i = 0
iteration6 = True
while iteration6:
print()
print('//' + chap[i])
print("if(ledState_" + chap[i] + " == true){")
print(' time_' + chap[i] + ' = time_' + chap[i] + ' - 1;')
print(' digitalWrite(PIN_' + chap[i] + ', HIGH);')
print(' }')
print()
print("if(time_" + chap[i] + " == 0){")
print(' ledState_' + chap[i] + ' = false;')
print(' }')
print()
print("if(ledState_" + chap[i] + " == false){")
print(' digitalWrite(PIN_' + chap[i] + ', LOW);')
print(' }')
i = i + 1
if i > 51:
iteration6 = False
print()
print('delay(1);')
print()
print('}')
print('NEW VERSION')
i = 26
iteration7 = True
while iteration7:
print()
print('//' + chap[i])
print("if(x == '" + chap[i] + "'){")
print(' digitalWrite (PIN_' + chap[i] + ', !digitalRead(PIN_' + chap[i] + '));')
print(' x = 0;')
print(' }')
i = i + 1
if i > 51:
iteration7 = False
print()
print('}')
print()
P.S.: Одной из целей автоматизации было избежать человеческих ошибок, каково же было моё удивление, когда скетч отказался компилироваться. Причина была в том, что я поторопился и написал алфавит с одной повторяющейся буковой.
P.P.S.: Заказчик был ужасно доволен, заплатил больше, чем договаривались, и даже разрешил поделиться кодом с читателями.
Учите Python, господа!
Комментарии (27)
Reckyxxx
26.07.2017 15:33Написав первые 26 #define, энтузиазм иссяк.
Тогда хотя бы:
chap = [chr(x) for x in range(97, 123)] + [chr(x).upper() for x in range(97, 123)] num = [str(x) for x in range(2, 54)]
qark
26.07.2017 15:59А лучше нагуглить или вспомнить
string.ascii_letters
иstring.ascii_uppercase
. Тогда и первого P.S. не было бы :)
vyacheslavteplyakov
26.07.2017 15:59+1Как говориться как кто умеет, была бы лень, а прогресс будет. Я даже не знаю как поступил был, скорее всего вообще использовал бы XL…
хотя дальше все сложнее, но мне просто лень.DEM_dwg
26.07.2017 17:15Решение с экселем выглядит очень лаконично, учитывая что сделать это можно меньше чем за минуту.
vyacheslavteplyakov
26.07.2017 17:56Да, буквально две «формулы» и протянуть вниз.
Первый столбик коды символов, второй рыба, третий превращение этих самых символов из первого столбика в буквы. Можно конечно завести алфавитный список в XL и «проятнуть», но это дольше. 4й порты (забыл их добавить к результату), ну и последний сращиваем все через & в одну строку, профит!
semen-pro
26.07.2017 18:29Excel мало подходит, для такого кода
if(ledState_a == true){ time_a = time_a - 1; digitalWrite(PIN_a, HIGH); }
QDeathNick
26.07.2017 22:47Очень подходит, попробуйте. Правда с телефона будет не просто это сделать, а вот с мышкой буквально секунды занимает.
Stronix
26.07.2017 16:30Вот это индусятина) Хотя бы как-то так:
for ch in string.ascii_letters: print('#define PIN_' + ch, string.ascii_letters.index(ch) + 2)
Учите Python, господа!
Ну, хоть самокритично)Lertmind
26.07.2017 17:18+1По-моему так получше будет:
import string for i, ch in enumerate(string.ascii_letters): print("#define PIN_{} {}".format(ch, i + 2))
Stronix
27.07.2017 08:40Тогда уж
import string for i, ch in enumerate(string.ascii_letters, start=2): print("#define PIN_{} {}".format(ch, i))
inferrna
26.07.2017 16:44Для питона есть удобный темплейтный движок mako — с ним можно получить читаемый код без этих обёрток в виде print(..). В частности, на нём работает кодогенерация в pyopencl.
kAIST
26.07.2017 16:57А зачем anaconda, если python из коробки в windows и так уже работает нормально? Какие то ещё батники писать… При установке нужно просто галочку поставить, чтоб нужные пути в path попали или сделать потом это ручками. А так и pip уже давно в комплекте идёт и работает прекрасно.
foxin
26.07.2017 17:03+2Я понимаю, что можно не быть хорошим программистом и при этом писать программы, хотя бы для ардуино. Но выкладывать это на хабр — как-то странно.
Gryphon88
26.07.2017 17:30+1На самом деле вопрос про внешнюю кодогенерацию интересный, потому что С:
— старый и не имеет части возможностей более новых языков. Например, объекты в чистом С дают неслабый оверхед.
— многословный
— с системой макросов, сложных и неинтуитивных. Например, иногда очень хочется сделать define внутри define, или сделать дефайн с генерацией имени через конкатенацию строк в макросе, или использовать if в макросе с раскруткой в compile time, или разделить токен в макросе на части — а низзя, если не брать в расчет извращения типа
g++ -E input.cpp | g++ -c -x c++ - -o output.o
примерно те же проблемы имеет asm
Поэтому в принципе разумно написать короткий понятный код на питоне или ещё на чём, который будет генерировать неподдерживаемый, но шустрый код на С/asm. Проблема в том, что нет устоявшегося мнения, как это делать «правильно»tronix286
27.07.2017 07:59На питоне простой понятный код будет тормозить, бай дизайн. Си конечно не идеален, и с обьектами там не очень. Но он быстрый. Просто нужно понимать разницу между задачей светодиодом моргнуть и скажем одновременного приема с трех SPI сообщений, с парсингом.
Gryphon88
27.07.2017 13:16Вот про это я и говорю, что нет устоявшегося мнения про «правильно». Если у нас задача в питоне сгенерировать текстовый файл на несколько тысяч строк, то он навряд ли будет тормозить так, что это станет неприемлемо, но зато мы теоретически сможем помочь gcc с оптимизацией и отбить время на компиляции. Задача становится ещё интереснее, если мы генерируем код на asm, потому, например, что там мы можем выходить из прерывания не туда, откуда в него вошли; такой код сложен в поддержке, но если его писать не на асме, может получить оба достоинства.
Правда, это ни у кого не получилось, чтоб аж прям выстрелить. Разработка компиляторов или кодогенераторов на прологе всплывает с 70х и по наши дни, но значимого выхлопа не видно.
Ссылки на компиляторы и кодогенераторы на прологе1.Applied logic — it's use and implementation as programming tool. Technical note, 1977
2. Parsing and Compiling Using Prolog, 1987
3. An implementation of retargetable code generators in prolog, 1988
4. Prolog based retargetable code generation, 1989
5. Code Generation — Concepts, Tools, Techniques: Proceedings of the International Workshop on Code Generation, Dagstuhl, Germany, 20–24 May 1991 глава 5, Prolog Implementation,
6. The Practice of Prolog, глава 4, Developing a parallelising Pascal compiler in Prolog (про Паскаль — потому что написано в стиле пошагового туториала), 1990
Видел и публикации 2010х, но там не так интересно и более специализировано
Konachan700
26.07.2017 19:06+1КДПВ, если расфокусировать зрение, тонко намекает нам на качество кода под катом.
Но если платили за количество строк, то понимаю, зачем так сурово…
QDeathNick
26.07.2017 22:39написал алфавит
А вы бы его на бумажке сначала писали, а потом проверили, перепечатывая, тогда бы скомпилилось.
kolodkin
27.07.2017 01:38Можно как-то так:
#define FIRST_PIN 2 #define LAST_PIN 27 #define PIN_COUNT (LAST_PIN - FIRST_PIN + 1) word timeout[PIN_COUNT]; word elapsed[PIN_COUNT]; void setup() { for (byte i = 0; i < PIN_COUNT; i++) { timeout[i] = 1000; elapsed[i] = 0; } for (byte i = FIRST_PIN; i <= LAST_PIN; i++) { pinMode(i, OUTPUT); pinMode(i + PIN_COUNT, OUTPUT); } Serial.begin(9600); } void loop() { if (Serial.available() > 0) { char x = Serial.read(); if ((x >= 'a') && (x < ('a' + PIN_COUNT))) { byte index = x - 'a'; byte pin = index + FIRST_PIN; elapsed[index] = timeout[index]; digitalWrite(pin, HIGH); } else if ((x >= 'A') && (x < ('A' + PIN_COUNT))) { byte index = x - 'A'; byte pin = index + LAST_PIN + 1; digitalWrite (pin, !digitalRead(pin)); } } delay(1); for (byte index = 0; index < PIN_COUNT; index++) { if (elapsed[index]) { if (--elapsed[index]) { char pin = index + FIRST_PIN; digitalWrite(pin, LOW); } } } }
Не проверял но общий смысл думаю понятен.
Hellsy22
27.07.2017 13:12Автор, это элементарная задача даже по меркам старших классов средней школы. Вы выбрали максимально громоздкий и чудовищно неудобный путь. Даже если бы у вас номера пинов шли не подряд, то следовало бы занести их в массив и обращаться к элементам массива. А уж в данном-то случае все вообще тривиально.
Надеюсь, что статьи программистов о разводке плат выглядят не так жалко и беспомощно…
old_gamer
27.07.2017 15:29можно еще все из-под условий в отдельные фунции выделить:
// установить а long set_a() { ledState_a = true; time_a = TIME_a; return 0; } //... void loop() { //... //a if(x == 'a'){ set_a(); x = 0; } // ... }
для каждой проверки отдельную функцию, само собой.
Gryphon88
На что только люди не идут, чтобы не учить макросы вообще и x-macro c _Generic в частности…