Comments 27
На что только люди не идут, чтобы не учить макросы вообще и x-macro c _Generic в частности…
Написав первые 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)]
Ъ-индусский код!
А с циклами и массивами пробовали то же самое написать?
Как говориться как кто умеет, была бы лень, а прогресс будет. Я даже не знаю как поступил был, скорее всего вообще использовал бы XL…

хотя дальше все сложнее, но мне просто лень.

хотя дальше все сложнее, но мне просто лень.
Решение с экселем выглядит очень лаконично, учитывая что сделать это можно меньше чем за минуту.
Да, буквально две «формулы» и протянуть вниз.
Первый столбик коды символов, второй рыба, третий превращение этих самых символов из первого столбика в буквы. Можно конечно завести алфавитный список в XL и «проятнуть», но это дольше. 4й порты (забыл их добавить к результату), ну и последний сращиваем все через & в одну строку, профит!
Первый столбик коды символов, второй рыба, третий превращение этих самых символов из первого столбика в буквы. Можно конечно завести алфавитный список в XL и «проятнуть», но это дольше. 4й порты (забыл их добавить к результату), ну и последний сращиваем все через & в одну строку, профит!
Excel мало подходит, для такого кода
if(ledState_a == true){
time_a = time_a - 1;
digitalWrite(PIN_a, HIGH);
}
Вот это индусятина) Хотя бы как-то так:
Ну, хоть самокритично)
for ch in string.ascii_letters:
print('#define PIN_' + ch, string.ascii_letters.index(ch) + 2)
Учите Python, господа!
Ну, хоть самокритично)
Для питона есть удобный темплейтный движок mako — с ним можно получить читаемый код без этих обёрток в виде print(..). В частности, на нём работает кодогенерация в pyopencl.
А зачем anaconda, если python из коробки в windows и так уже работает нормально? Какие то ещё батники писать… При установке нужно просто галочку поставить, чтоб нужные пути в path попали или сделать потом это ручками. А так и pip уже давно в комплекте идёт и работает прекрасно.
Я понимаю, что можно не быть хорошим программистом и при этом писать программы, хотя бы для ардуино. Но выкладывать это на хабр — как-то странно.
На самом деле вопрос про внешнюю кодогенерацию интересный, потому что С:
— старый и не имеет части возможностей более новых языков. Например, объекты в чистом С дают неслабый оверхед.
— многословный
— с системой макросов, сложных и неинтуитивных. Например, иногда очень хочется сделать define внутри define, или сделать дефайн с генерацией имени через конкатенацию строк в макросе, или использовать if в макросе с раскруткой в compile time, или разделить токен в макросе на части — а низзя, если не брать в расчет извращения типа
примерно те же проблемы имеет asm
Поэтому в принципе разумно написать короткий понятный код на питоне или ещё на чём, который будет генерировать неподдерживаемый, но шустрый код на С/asm. Проблема в том, что нет устоявшегося мнения, как это делать «правильно»
— старый и не имеет части возможностей более новых языков. Например, объекты в чистом С дают неслабый оверхед.
— многословный
— с системой макросов, сложных и неинтуитивных. Например, иногда очень хочется сделать define внутри define, или сделать дефайн с генерацией имени через конкатенацию строк в макросе, или использовать if в макросе с раскруткой в compile time, или разделить токен в макросе на части — а низзя, если не брать в расчет извращения типа
g++ -E input.cpp | g++ -c -x c++ - -o output.o
примерно те же проблемы имеет asm
Поэтому в принципе разумно написать короткий понятный код на питоне или ещё на чём, который будет генерировать неподдерживаемый, но шустрый код на С/asm. Проблема в том, что нет устоявшегося мнения, как это делать «правильно»
На питоне простой понятный код будет тормозить, бай дизайн. Си конечно не идеален, и с обьектами там не очень. Но он быстрый. Просто нужно понимать разницу между задачей светодиодом моргнуть и скажем одновременного приема с трех SPI сообщений, с парсингом.
Вот про это я и говорю, что нет устоявшегося мнения про «правильно». Если у нас задача в питоне сгенерировать текстовый файл на несколько тысяч строк, то он навряд ли будет тормозить так, что это станет неприемлемо, но зато мы теоретически сможем помочь gcc с оптимизацией и отбить время на компиляции. Задача становится ещё интереснее, если мы генерируем код на asm, потому, например, что там мы можем выходить из прерывания не туда, откуда в него вошли; такой код сложен в поддержке, но если его писать не на асме, может получить оба достоинства.
Правда, это ни у кого не получилось, чтоб аж прям выстрелить. Разработка компиляторов или кодогенераторов на прологе всплывает с 70х и по наши дни, но значимого выхлопа не видно.
Правда, это ни у кого не получилось, чтоб аж прям выстрелить. Разработка компиляторов или кодогенераторов на прологе всплывает с 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х, но там не так интересно и более специализировано
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х, но там не так интересно и более специализировано
написал алфавит
А вы бы его на бумажке сначала писали, а потом проверили, перепечатывая, тогда бы скомпилилось.
Можно как-то так:
Не проверял но общий смысл думаю понятен.
#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);
}
}
}
}
Не проверял но общий смысл думаю понятен.
Почему не использовали switch() case:?
Автор, это элементарная задача даже по меркам старших классов средней школы. Вы выбрали максимально громоздкий и чудовищно неудобный путь. Даже если бы у вас номера пинов шли не подряд, то следовало бы занести их в массив и обращаться к элементам массива. А уж в данном-то случае все вообще тривиально.
Надеюсь, что статьи программистов о разводке плат выглядят не так жалко и беспомощно…
Надеюсь, что статьи программистов о разводке плат выглядят не так жалко и беспомощно…
можно еще все из-под условий в отдельные фунции выделить:
для каждой проверки отдельную функцию, само собой.
// установить а
long set_a() {
ledState_a = true;
time_a = TIME_a;
return 0;
}
//...
void loop() {
//...
//a
if(x == 'a'){
set_a();
x = 0;
}
// ...
}
для каждой проверки отдельную функцию, само собой.
Настоящий китайский код :)
Sign up to leave a comment.
Как я писал код для Arduino с помощью Python