Урок 4. Основы программирования Ардуино на языке C.

CC

Этот урок дает минимальные знания, необходимые  для программирования  систем Ардуино  на языке C. Можно только просмотреть его и в дальнейшем использовать как справочную информацию. Тем, кто программировал на C в других системах можно пропустить статью.

Предыдущий урок     Список уроков     Следующий урок

Повторю, что это минимальная информация. Описание указателей, классов, строковых переменных и т.п. будет дано в последующих уроках. Если что-то окажется непонятным, не беспокойтесь. В дальнейших уроках будет много примеров и пояснений.

 

Структура программы Ардуино.

Структура программы Ардуино  достаточно проста и в минимальном варианте состоит из двух частей setup() и loop().

void setup()  {

//  код выполняется один раз при запуске программы

}

void loop()  {

// основной код, выполняется в цикле

}

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

После завершения setup() управление переходит к функции loop().  Она в бесконечном цикле выполняет команды, записанные в ее теле (между фигурными скобками). Собственно эти команды и совершают все алгоритмические действия контроллера.

Первоначальные правила синтаксиса языка C.

;  точка с запятой  Выражения могут содержать сколь угодно много пробелов, переносов строк. Признаком завершения выражения является символ ”точка с запятой ”.

z = x + y;
z=      x      
+ y     ;

{   }  фигурные скобки определяют блок функции или выражений. Например, в функциях setup() и loop().

/* … */ блок комментария, обязательно закрыть.

/* это блок      комментария  */

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

// это одна строка комментария

Переменные и типы данных.

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

Тип данных Разрядность, бит Диапазон чисел
boolean 8 true, false
char 8 -128 … 127
unsigned char 8 0 … 255
byte 8 0 … 255
int 16 -32768 … 32767
unsigned int 16 0 … 65535
word 16 0 … 65535
long 32 -2147483648 … 2147483647
unsigned long 32 0 … 4294967295
short 16 -32768 … 32767
float 32 -3.4028235+38 … 3.4028235+38
double 32 -3.4028235+38 … 3.4028235+38

Типы данных выбираются исходя из требуемой точности вычислений, форматов данных и т.п. Не стоит, например, для счетчика, считающего до 100, выбирать тип long. Работать будет, но операция займет больше памяти данных и программ, потребует больше времени.

 

Объявление переменных.

Указывается тип данных, а затем имя переменной.

int x;                      // объявление переменной с именем x типа int
float widthBox;   // объявление переменной с именем widthBox типа float

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

Переменная может быть объявлена в любой части программы, но от этого зависит, какие блоки программы могут ее использовать. Т.е. у переменных есть области видимости.

  • Переменные, объявленные в начале программы, до функции void setup(), считаются глобальными и доступны в любом месте программы.
  • Локальные переменные объявляются внутри функций или таких блоков, как цикл for, и могут использоваться только в объявленных блоках. Возможны несколько переменных с одним именем, но разными областями видимости.

int mode;           // переменная доступна всем функциям

void setup()  {
//  пустой блок, начальные установки не требуются

}

void loop()  {

long  count;                     // переменная count доступна только в функции loop()

for ( int i=0; i < 10;)      // переменная i доступна только внутри цикла   
  {
     i++;
    }
}

При объявлении переменной можно задать ее начальное значение (проинициализировать).

int x = 0;              // объявляется переменная x с начальным значением 0
char d = ‘a’;        // объявляется переменная d с начальным значением равным коду символа ”a”

При арифметических операциях с разными типами данных происходит автоматическое преобразование типов данных. Но лучше всегда использовать явное преобразование.

int x;                     // переменная int
char y;                  // переменная char
int z;                     // переменная int

z = x + (int) y;     // переменная y явно преобразована в int

Арифметические операции.

= присваиваниее
+ сложение
- вычитание
* произведение
/ деление
% остаток от деления

Операции отношения.

== равно
!= не равно
< меньше
> больше
<= меньше или равно
>= больше или равно

Логические операции.

&& логическое И
|| логическое ИЛИ
! логическое НЕ

Операции над указателями.

* косвенная адресация
& получение адреса переменной

Битовые операции.

& И
| ИЛИ
^ ИСКЛЮЧАЮЩЕЕ ИЛИ
~ ИНВЕРСИЯ
<< СДВИГ ВЛЕВО
>> СДВИГ ВПРАВО

Операции смешанного присваивания.

++ + 1 к переменной
-- - 1 к переменной
+= сложение
-= вычитание
*= умножение
/= деление
%= остаток от деления
&= битовое И
|= битовое ИЛИ

 

Выбор вариантов, управление программой.

Оператор IF проверяет условие в скобках и выполняет последующее выражение или блок в фигурных скобках, если условие истинно.

if (x == 5)             // если x=5, то выполняется z=0  
z=0;

if (x > 5)               // если x > 5, то выполняется блок z=0, y=8;
{    z=0;    y=8; }

IF … ELSE позволяет сделать выбор между двух вариантов.

if (x > 5)               // если x > 5, то выполняется блок z=0, y=8;
 {
   z=0;
   y=8;
  }
 else                       // в противном случае выполняется этот блок
 {
   z=0;
   y=0;
  }

ELSE IF – позволяет сделать множественный выбор

if (x > 5)               // если x > 5, то выполняется блок z=0, y=8;
  {
    z=0;
    y=8;
   }

else if (x > 20)   // если x > 20, выполняется этот блок
  {
   }

else                       // в противном случае выполняется этот блок
  {
   z=0;
   y=0;
   }

SWITCH CASE - множественный выбор. Позволяет сравнить переменную (в примере это x) с несколькими константами (в примере 5 и 10) и выполнить блок, в котором переменная равна константе.

switch (x)  {

case 5 :     
     // код выполняется если  x = 5
      break;

case 10 :
     // код выполняется если  x = 10
     break;

default :
     // код выполняется если  не совпало ни одно предыдущее значение
     break;
}

Цикл FOR. Конструкция позволяет организовывать циклы с заданным количеством итераций. Синтаксис выглядит так:

for ( действие до начала цикла;
         условие продолжения цикла;
        действие в конце каждой итерации )  {

// код тела цикла

}

Пример цикла из 100 итераций.

for ( i=0; i < 100; i++ )     // начальное значение 0, конечное 99, шаг 1

{
     sum = sum + I;
}

Цикл WHILE. Оператор позволяет организовывать циклы с конструкцией:

while ( выражение )
{
// код тела цикла
}

Цикл выполняется до тех пор, пока выражение в скобках истинно. Пример цикла на 10 итераций.

x = 0;
while ( x < 10 )
 {
  // код тела цикла
   x++;
  }

DO WHILE – цикл с условием на выходе.

do
{
  // код тела цикла
}   while ( выражение );

Цикл выполняется пока выражение истинно.
BREAK – оператор выхода из цикла. Используется для того, чтобы прервать выполнение циклов  for, while, do while.

x = 0;
while ( x < 10 )
{
  if ( z > 20 ) break;             // если z > 20, то выйти из цикла
// код тела цикла
  x++;
  }

GOTO – оператор безусловного перехода.

goto  metka1;                   // переход на metka1
………………
metka1:

CONTINUE -  пропуск операторов до конца тела цикла.

x = 0;
while ( x < 10 )
{
// код тела цикла
if ( z > 20 ) continue;      // если z > 20, то вернуться на начало тела цикла
// код тела цикла
x++;
 }

Массивы.

Массив это область памяти, где последовательно хранятся несколько переменных.

Объявляется массив так.

int ages[10];                      // массив из 10 переменных типа int

float weight[100];          // массив из 100 переменных типа float

При объявлении массивы можно инициализировать:

int ages[10] = { 23, 54, 34, 24, 45, 56, 23, 23, 27, 28};

Обращаются к переменным массивов так:

x = ages[5];        // x присваивается значение из 5 элемента массива.
ages[9] = 32;      // 9 элементу массива задается значение 32

Нумерация элементов массивов всегда с нуля.

Функции.

Функции позволяют выполнять одни и те же действия с разными данными. У функции есть:

  • имя, по которому ее вызывают;
  • аргументы – данные, которые функция использует для вычисления;
  • тип данных, возвращаемый функцией.

Описывается пользовательская функция вне функций setup() и loop().

void setup()  {
//  код выполняется один раз при запуске программы
}

void loop()  {
 // основной код, выполняется в цикле
}

// объявление пользовательской функции с именем functionName
type  functionName( type argument1, type argument1, … , type argument)
   {
    // тело функции
     return();
   }

Пример функции, вычисляющей сумму квадратов двух аргументов.

int sumQwadr (int  x, int y)
{
  return( x* x + y*y);
}

Вызов функции происходит так:

d= 2; b= 3;
z= sumQwadr(d, b);                    // в z будет сумма квадратов переменных d и b

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

Очень коротко, но этих данных должно хватить для того, чтобы начать писать программы на C для систем Ардуино.

Последнее, что я хочу рассказать в этом уроке, как принято оформлять программы на C. Думаю, если вы читаете этот урок в первый раз, стоит пропустить этот раздел и вернутся к нему позже, когда будет что оформлять.

 

Рекомендации по оформлению программ на языке C.

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

Имена в языке C.

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

Signal, TimeCount

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

signal, timeCount

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

MAX_TEMP, RED

Методы и функции должны быть названы глаголами, записанными в смешанном регистре, первая буква в нижнем регистре.

getTime, setTime

Об остальных формальностях в следующих уроках, по мере необходимости.

 

В следующем уроке напишем первую программу, научимся считывать данные с цифровых портов и управлять их состоянием.

 

Предыдущий урок     Список уроков     Следующий урок

6

Автор публикации

не в сети 3 дня

Эдуард

279
Комментарии: 1936Публикации: 197Регистрация: 13-12-2015

84 комментария на «Урок 4. Основы программирования Ардуино на языке C.»

  1. На странице

    http://mypractic.ru/urok-4-osnovy-programmirovaniya-arduino-na-yazyke-c.html

    в тексте

    «…первая буква прописная (нижний регистр).»

    описка — д.б. «строчная» вместо «прописная»: «прописная» есть синоним «заглавная».

    А вообще, изложение великолепно! Со времён талмудов Ритчи (D.Ritchie) и Bjarne Stroustrup (TAMU) пришло, наконец, понимание методологии изложения. Спасибо!

    0
  2. Содержание функции sumQwadr неправильное. Надо так:

    int sumQwadr(int x, int y)
    {
    return x*x + y*y;
    }

    0
    • Действительно, ошибка новичка, да еще и не исправлена до сих пор.

      В теле функции sumQwadr объявляются переменные которые перекрывают входные параметры функции, да еще они не инициализированы. Результат работы донной функции будет непредсказуем, да и скорее всего компилятор выдаст ошибку.

      0
  3. Функция setup() выполняется один раз, при включении питания или сбросе контроллера. Обычно в ней происходят начальные установки переменных, регистров.

    А в уроке 6:
    boolean flagPress= false;
    boolean flagClick= false;
    byte buttonCount= 0;

    void setup() {…}

    Т.е. можно инициализировать до Setup?

    0
    • Это инициализация переменных при объявлении. При создании переменных компилятор задает им указанные значения.

      0
  4. После создания цикла for , к примеру (i=0, i<10, i++), в теле цикла мне нужно что бы некое действие, к примеру digitalWrite(13, HIGH); , выполнялось при 4 < i < 8. в теле "FORа" использую оператор if ( 4 < i 8.
    вариант if (i>4, i<8) тоже не работает.
    "if — else if — else" тоже не помогло. Подскажите, как поместить переменную i в нужный мен интервал?

    0
    • Несколько условий в операторе if выглядят так:
      if ( i > 4 && i < 8). Выполняется если одновременно верны два условия i > 4 и i < 8.

      0
  5. void setup() {

    // код выполняется один раз при запуске программы

    }
    Можно ли из loop вызывать setup?

    0
    • Не знаю. А зачем. Лучше так не делать. Если надо перезагрузить систему лучше использовать метод из урока 16. Или какой-нибудь другой подобный.

      0
  6. «Обращаются к переменным массивов так:

    x = ages[5]; // x присваивается значение из 5 элемента массива.
    ages[9] = 32; // 9 элементу массива задается значение 32

    Нумерация элементов массивов всегда с нуля.»

    Мне кажется вы не правы здесь.
    ages[5] это ШЕСТОЙ элемент массива ages, т.к. «Нумерация элементов массивов всегда с нуля».

    0
      • Примечание:Следует запомнить, что отсчет элементов массива начинается с 0, а не с 1. Это источник частых ошибок новичков в программах на C++. Если используется массив, состоящий из 10 элементов, то для обращения к элементам массива используются индексы от ArrayName[0] до ArrayName[9]. Обращение ArrayName[10] будет ошибочным.
        Перевод книги Джесс Либерти Освой самостоятельно C++ за 21 день.
        Вы в тексте обращаетесь к 6-му и 10-му элементам массива с адресами ages[5] и ages[9].

        0
        • У Вас очень качественный материал по два три раза перечитываю. Спасибо Вам за эти уроки. Прошу не обижаться на замечания.

          0
          • Спасибо за отзыв. На критику я никогда не обижаюсь. Многие замечания по делу. Только надо учитывать, что я пишу уроки по остаточному принципу. Не всегда хватает времени все тщательно продумать.

            0
        • Константин, любому понятно, что называть элемент удобнее и понятнее по присвоенному номеру, а не по порядковому. поэтому ages[0] и ages[9] это соответственно 0-й и 9-й элементы.

          0
  7. Эдуард здравствуйте! Честно говоря — очень удивлён Вашими уроками. Ни где более я не встречал более доходчивых и информативных уроков — спасибо Вам огромное! У меня вопрос — вот функция void Setup () выполняется только один раз при запуске микроконтроллера. После того, как функция отработала — что происходит с переменными, объявленными внутри этой функции и которые более не нужны? Освобождается ли занимаемаемая ими память? Или для этого надо предпринимать какие либо меры самостоятельно?

    0
    • Здравствуйте!
      Спасибо за добрые слова. Переменные в setup подчиняются обычному правилу области видимости переменных. Если они объявлены в этой функции, то это локальные переменные. При выходе из функции переменные будут уничтожены, память освобождена.

      0
  8. Немного уточнить.Пусть:
    int i1;
    int i2=10;
    setup()
    {
    int i3=20;
    }
    На ассемблере будет выглядеть так?:
    сначала в ячейку(i1) засылаем значение по умолчанию, потом в ячейку (i2) засылаем 10 и только в последнюю очередь засылаем в ячейку (i3) 20 ?

    0
  9. Добрый день, ребят.
    есть такой вопрос:
    pinMode (A0, INPUT);
    pinMode (A1, INPUT);
    pinMode (A2, INPUT);
    pinMode (A3, INPUT);
    pinMode (A4, INPUT);
    pinMode (A5, INPUT);
    pinMode (A6, INPUT);
    pinMode (A7, INPUT);
    можно ли эту инициализацию записать типа циклом в 1-2 строчки?
    я попытался так: for (int i=0; i<=7; i++) {pinMode (A(i),INPUT);}
    но не получилось… сильно не ругайте, пожалуйста…

    0
    • Здравствуйте!
      Функция pinMode() в качестве первого аргумента требует целочисленную переменную. А вы указываете неизвестную компилятору функцию A().
      Аналоговым входам A0… соответствуют номера выводов, начиная с 14го. Т.е. можно сделать так:
      for (int i=14; i< =19; i++) {pinMode (i,INPUT);}

      0
  10. Попробовал сделать функцию со значениями по умолчанию->
    ардуино ругается! И ещё передал в функцию аргументы по ссылке -> получилась какая-то галиматья. Ни подскажите в чём дело?

    0
  11. uint8_t => unsignet, integer ,8 -количество бит, тип.
    а в табличке переменных unsigned int, это 16 бит . таким образом я так понимаю можно моделировать тип переменной, — не проще использовать Byte , это ведь тоже самое? или я не прав.

    0
    • Здравствуйте!
      uint8_t аналогично byte. А использовать ли ее, зависит от задачи. Если диапазон переменной (0…255) позволяет, то да.

      0
      • Спасибо. Это я понял, меня интересует — почему используют именно такую форму записи, это какая-то фишка? в чем ее преимущества?

        0
        • Здравствуйте!
          Кто как привык. Раньше для 8ми разрядного беззнакового числа в основном использовали тип unsigned char.

          0
  12. Эдуард, здравствуйте. Я новичок, правда мне под 50. Увлекся программированием микроконтроллеров (давно мечтал). Есть небольшие личные достижения, но не хватаем опыта. На мой взгляд мне не хватает знаний и опыта в создании структуры программы, ее алгоритма. Пожалуйста, расскажите, как Вы, исходя из задачи, придумываете и формируете будущую программу. Может это какие-то схемы или рисунки. Будет интересно изучить Ваш опыт.

    0
    • Здравствуйте!
      Начиная с урока 36 я поэтапно веду разработку контроллера элемента Пельтье. Посмотрите в этих уроках сам принцип разработки, даже пока не понимая программных решений.

      0
      • Спасибо за Ваш проект, Эдуард!
        Изучаю несколько подобных проектов, но именно Ваш —
        новая и высокая ступень к знаниям С++! Иногда приходится пошевелить мозгами, чтобы понять Вас, но освоив урок, ни сколько не жалею о потраченных времени и усилиях.

        0
    • Александр Васильевич, раньше (в 90-х) нас в школе заставляли сначала писать блок-схему программы. Теперь я пон6имаю как это оказалось полезно. Можно писать программы без компьютера (было дело в ресторане на салфетке писали, спорили, создавали)

      0
  13. Здравствуйте, огромное СПАСИБО за такой подробный курс.
    Для таких начинающих как я, было бы здорово дополнить все это блок схемами.

    0
    • Здравствуйте! Спасибо за отзыв.
      Я стараюсь максимально подробно пояснять материал, в том числе и с использованием блок-схем.

      0
      • Еще раз спасибо за уроки и Ваши ответы. Думаю первая трудность у нас (новичков) встречается уже на уроке по обработке дребезга контактов кнопки, там и нужна блок-схема.

        0
  14. Всё отлично пишите, но естественно что встречаются досадные описки:
    «Переменные должны быть записаны именами в смешанном регистре, первая буква срочная (нижний регистр).»

    В таблице типов Вы написали «Диапазон чисел», хотя «true,false» — это значение. Я думаю было бы правильнее написать «Диапазон значений».

    Возможно я не прав.

    0
    • Спасибо, исправлю.
      Наверное, правильно «диапазон значений чисел». Но мне кажется, как сокращенный вариант, допустим и «диапазон чисел». Особенно в таблице.

      0
  15. Здравствуйте. Поясните пожалуйста, почему boolean прописывается true или false? я попробовал написать
    boolean x;
    void setup()
    {
    Serial.begin(9600);
    }
    void loop()
    {
    x = true; // присваиваем переменной х значение true
    Serial.println(x); // выводим значение х в порт
    x = false; // присваиваем переменной х значение false
    Serial.println(x); // выводим значение х в порт
    delay(1000);
    }
    В мониторе порта видим смену 0 и 1. Вроде получается проще и понятнее сразу работать с 0 и 1.

    0
    • Здравствуйте!
      При объявлении переменной типа boolean выделяется байт памяти. Состоянию false соответствует значение 0, все остальные значения это false. Поэтому ваше предложение вполне работоспособно. Но когда вы используете false и true, программа лучше читается. Видно, что эту переменную вы создали для логических операций. Я советую придерживаться традиционного подхода.

      0
  16. Коментарии приведены для c++. В классическом Си только такой вариант /*КОММЕНТАРИЙ */. Я так понмаю, что в статье не делается акцент на различие синтаксиса С или С++, чем можно ввести в заблуждение. Лучше тогда везде указывать С++ это будет правильнее. Поправите меня, если я не прав

    0
  17. Здравствуйте!
    Кажется в примере для оператора ELSE IF есть недочет.
    Будет выполняться или первый блок или последний.

    0
  18. Спасибо за толковое изложение.
    Уже было начал радоваться интересному найденному ресурсу, призванному расширить кругозор увлечённого человека, но тут увидел «нижнее подчёркивание» и рухнул на землю.

    Эдуард, оно всегда нижнее, согласно правилам русского языка.
    Задумайтесь. За материал спасибо.

    0
    • Сергей, это программерский сленг.
      Слово «подчёркивание» обозначает у программеров символ с подчёркиванием под ним. «Нижнее подчёркивание» — знак подчёркивания «_» без символа.
      Да, не совсем грамотно. Но так сложилось.

      0
    • Это повелось, Сергей, когда у нас ещё не было всяких Word’ов и мониторов с графикой. А только символьные.
      Подчёркивание строки тогда осуществлялось с помощью символов следующей строки.

      Например:
      абвгд
      ——- — строка с обычным подчёркиванием. Используется «-»

      абвгд
      ===== — строка с двойным подчёркиванием. Используется «=»

      абвгд
      _____ — строка с нижним подчёркиванием. Используется «_»

      Т.е. «минус» это обычное подчёркивание, а «_» — нижнее.

      0
  19. Может быть кому-нибудь будет интересно как стандартизован С/С++ (http://geosoft.no/development/cppstyle.html). Много вопросов отпадёт.

    0
  20. здравствуйте. допущена ошибка в примере с условием и альтернативными условиями допущена ошибка. (if (x>5)… else if (x>20)…). например при значении х=25 выполниться 1 условие

    0
  21. Новичку тут ничего не понятно что писать когда писать и для чего все непонятно

    0
  22. Здравствуйте Эдуард!
    не могли бы вы подсказать, как при помощи внешнего прерывания 0 (или 1 )
    attachInterrupt(0, ??????????, LOW);
    выполнить переход на определенный участок программы типа
    goto metka1;
    возвращаться на место в котором поступило прерывание не нужно.
    спасибо!

    0
    • Здравствуйте!
      Если вам требуется такая операция, то скорее всего, у вас не оптимальная структура программы. Но можете попробовать так.

      volatile boolean flagInt=false;

      void setup() {
      attachInterrupt(0, myInterrupt, FALLING);
      }

      void loop() {

      if( flagInt == true ) {
      flagInt= false;
      goto metka1;
      }
      }

      void myInterrupt() {
      flagInt= true;
      }

      0
  23. Эдуард, благодарю за участие!
    но к железу доступ будет только на следующие выходные, а в симуляторе я попробовал — не работает (ни как не реагирует), в качестве сигнала прерывания кнопка, замыкающая D2 на GND
    возможно, что этот симулятор не поддерживает внешние прерывания
    https://www.tinkercad.com/things/9FCbR0ZCEnz-terrific-amur/editel?tenant=circuits
    суть в том, что мне нужно чтобы при срабатывании внешнего прерывания(0), отрабатываемый в этот момент участок программы, мгновенно прерывался (именно мгновенно) и начинал выполнятся совершенно другой участок программы и выполнялся и прерывался точно так же до прихода второго прерывания(1)

    0
  24. Эдуард добрый день!
    проверил я в железе, (да и в симуляторе тоже разобрался) предложенный вами вариант не работает как внешнее прерывание, т.е. выполнение программы не прерывается, а продолжается пока не дойдет до команды
    if( flagInt == true ) {
    flagInt= false;
    goto metka1;
    }
    после этого выполняется переход на metka1, но это же совсем не то, для такой работы совсем не нужно выполнять внешнее аппаратное прерывание.
    если вас не затруднит помогите пожалуйста!

    0
  25. Добрый день Эдуард
    Интересует вопрос как можно внутри одной функции опредиль другую функцию. То есть получается вложение одной функции в другую. Поиск на просторах интернета ничего толкового не дал. Заранее благодарен.

    0
    • Здравствуйте!
      Насколько я знаю, в языке Си запрещены вложенные функции. Но они реализованы в расширении GCC.

      0
  26. ……Имена, представляющие типы данных,
    Signal, TimeCount……
    Эдуард, я новичок в С++, не понял, что это такое и чем это отличается от переменной?
    Переменная — это ведь тоже «данные-аргументы» для вычислений?

    0
    • Здравствуйте!
      int x;
      x — это имя переменной
      int — тип данных.
      В СИ существуют сложные типы данных. Им можно давать имена. Получаются свои типы данных. Например.
      struct Date
      {
      byte day;
      byte month;
      unsigned int year;
      };

      Date — это тип данных. Создание переменной типа Date:
      Date myBirthday;
      myBirthday — это переменная

      0
      • Спасибо за ответ. Хочется сразу делать программы не нарушая правил. Переучиваться потом — гораздо хуже.

        0
  27. Добрый день. Простите что указываю, но в структуру цикла:
    DO WHILE – цикл с условием на выходе.

    do
    {
    // код тела цикла
    } while ( выражение );

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

    0
  28. Здравствуйте , Эдуард! Подскажите пожалуйста, что я делаю неправильно… Хочу сделать цикл с четырьмя итерациями, чтобы в начале каждой программа ожидала нажатие кнопки и только затем выполняла код. На деле же получается, что после первого нажатия программа выполняет цикл всех четырёх итераций без ожидания последующих нажатий.

    void loop(){
    int n;
    int i=4;
    int sum=0;

    char customKey = customKeypad.getKey();
    while (i—) {

    switch (customKey) {
    case ‘1’ : { n = 1;
    Serial.println(n);
    sum = sum*10 + n;
    Serial.println(sum);
    }
    break;
    }
    }

    0
    • Здравствуйте!
      А где у вас происходит ожидание кнопки?
      Я с библиотекой Keypad не работал.
      Начните с того, что выведите код нажатой кнопки. Как-то так. char customKey = customKeypad.getKey();
      if( customKey != 0 ) {
      // кнопка нажата
      Serial.println(customKey);
      }
      При удержании кнопки на экране монитора последовательного порта будет бежать код нажатой кнопки.
      Затем выделите событие нажатия кнопки. При каждом нажатии должен выдаваться один код. И только потом добавляйте в программу свои действия по нажатию кнопки.

      0
  29. Если закомментировать цикл , то символы выводятся. Иначе , не работает… #include
    const byte ROWS = 4; //four rows
    const byte COLS = 4; //four columns
    //define the cymbols on the buttons of the keypads
    char hexaKeys[ROWS][COLS] = {
    {‘1′,’2′,’3′,’R’},
    {‘4′,’5′,’6′,’n’},
    {‘7′,’8′,’9′,’S’},
    {‘C’,’0′,’E’,’I’}
    };
    byte rowPins[ROWS] = {9, 8, 7, 6}; //connect to the row pinouts of the keypad
    byte colPins[COLS] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad

    //initialize an instance of class NewKeypad
    Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

    void setup() {
    Serial.begin(9600);
    }

    void loop() {
    char customKey = customKeypad.getKey();
    for (int i=3; i=0;i—) {
    if( customKey != 0 ) {
    Serial.println(customKey);

    }
    }
    }

    0
  30. Исправил. Теперь выдаёт 3 значения по одному нажатию. А как сделать чтобы выдало одно значение и ждало следующего нажатия ?

    0
  31. “Имена типов данных и классов принято писать с большой буквы. Пример: Signal, Servo”
    Что такое имена типов данных, можно примеры в какой либо строке кода. Ведь типы данных это
    это например : uint16_t , unsigned char , long и т.д. То есть все имена типов не начинаются большой буквы.

    0
    • Здравствуйте!
      Базовые типы данных в языке Си пишутся со строчной буквы.
      Сложные, вновь создаваемые типы данных — с прописной. Дальше будет урок про классы, в нем есть примеры.

      0

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Нажимая кнопку "Отправить" Вы даёте свое согласие на обработку введенной персональной информации в соответствии с Федеральным Законом №152-ФЗ от 27.07.2006 "О персональных данных".