User Tools

Site Tools


en:arduino_module_base_lesson

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

en:arduino_module_base_lesson [2020/01/20 16:15]
golikov
en:arduino_module_base_lesson [2020/03/25 16:28]
Line 1: Line 1:
-======Getting Started====== 
  
-==== Messaging Basics ==== 
- 
-Only the orbiter control computer can initiate communications over the construction set bus. It can query various devices on the bus, including Arduino, in points of time specified by the user. It can also receive responses but only for a limited time that can be defined by the user using the function shown below. Therefore every time we want to initiate transfers or receive commands with Arduino there must be an explicit command to perform such an operation in the orbiter program. 
- 
-==== Orbiter-Side Messaging ==== 
- 
-The following function invokes commands for interacting with Arduino: 
-<code c> 
-int arduino_send(const uint16_t num, const uint16_t msg_id, char *args, char *answer, char *timeout) 
-</​code>​ 
- 
-  * The first argument is the Arduino index number (defaults to 0) 
-  * The second argument is the message ID (as necessary on the Arduino side depending on the program being executed) 
-  * The third argument is the data being transferred (NULL if none) 
-  * The fourth argument is the buffer to receive data (NULL if there is nothing to be received) 
-  * The fifth argument is the time to wait for a response from Arduino (in milliseconds). This value must be chosen by the user depending on the particular objective. 
- 
-====Arduino-Side Messaging==== 
- 
-The Arduino side uses a special library orbicraftBus.arduinoLib.zip providing various methods for working with the bus of the construction set. 
- 
-**Description of methods:** 
- 
-**Message Receipt Function** \\ 
-When a new message arrives it is written into the msg variable. The function returns message length in bytes (including identifiers),​ returning 0 when there is no message. -1 will be returned if there was a decoding error. 
-<code c> 
-int16_t takeMessage(Message &msg) 
-</​code>​ 
- 
-The Message structure contains the following fields: 
-  * from: sender ID 
-  * to: recipient ID 
-  * id: message ID 
-  * data: a string of arguments 
- 
-**Message Sending Function** \\ 
-Returns the length of the message sent in bytes. 
-<code c> 
-int16_t sendMessage(const uint16_t address, const uint16_t id, const String data) 
-</​code>​ 
- 
-  * address: recipient address 
-  * id: message ID 
-  * data: a string of arguments 
- 
-**Received Data Buffering Function** \\ 
-This method must be called from the serialEvent2() function – see sample code. 
-<code c> 
-void serialEventProcess(void) 
-</​code>​ 
- 
-**Device ID Setting Function** \\ 
-This function is necessary if there are multiple Arduino controllers on the bus. 
- 
-<code c> 
-void setArduinoNumber(const uint8_t newNumber) 
-</​code>​ 
-newNumber is the new device number. ​ 
- 
-**Function Returning the Device Number** 
-<code c> 
-uint8_t getArduinoNumber(void) ​ 
-</​code>​ 
- 
-<note tip> 
-Understanding the details of interoperation between the Orbicraft Construction Set and Arduino requires you to learn the [[https://​en.wikipedia.org/​wiki/​Consistent_Overhead_Byte_Stuffing|COBS]] data transfer protocol along with some basics of object-oriented programming as you will encounter related terminology in code examples. We highly recommend you do that in order to grasp the principles behind the operation of the construction set data bus and its interoperation with the payload. A certain basic level of proficiency with the C/C++ programming language will also be necessary for writing code. 
-</​note>​ 
- 
-=====Transferring Commands to Arduino===== 
- 
-If you have not done it yet, take some time to read the Getting Started section where the necessary preparations are explained. 
- 
-In line with what has become a tradition in Arduino world, our first example will be a program that blinks the built-in LED. This LED is noted as DIR_LED on the shield. It should be noted that a built-in LED connected to pin 13 will also light up on the Arduino board. 
- 
-Our approach to the use of arduino_send() will be as follows. By merely sending a message ID from the orbiter computer we will invoke an already existing function on the Arduino side implemented in the traditional Arduino way. 
- 
-**Orbiter-Side Code** 
- 
-Here our task is to send a message with an ID that will be used to invoke a function in Arduino. 
- 
-<note tip> 
-See Getting Started for a refresher on how to design programs for the orbiter computer correctly. 
-</​note>​ 
- 
-<file c ArduinoTestLed_1_Orbi.c>​ 
-#include "​libschsat.h"​ 
- 
-void control(void) 
-{ 
-  
- /*  
- * Transfer a command for executing command ID 1 to Arduino using the arduino_send built-in function 
- * The first argument is the Arduino ID (defaults to 0) 
-        * The second argument is message ID (1 in our case) 
-        * The third argument is the data being transferred (NULL as we don’t have any data to send) 
-        * The fourth argument is the buffer to receive data (NULL as we don’t expect a response) 
-        * The fifth argument is the time to wait for a response from Arduino (100 ms in this case but it matters little in this case as we aren’t waiting for any response) 
- */ 
- 
- arduino_send(0,​ 1, NULL, NULL, 100); 
-  
-} 
-</​file>​ 
- 
-====Arduino Code==== 
- 
-Our task is to turn on the built-in LED for 3 seconds by sending a command from the orbiter computer and then turn it off. In order to accomplish that we must receive a packet containing an ID from the orbiter computer and execute the respective command by calling the LED control function. 
- 
-<note tip> 
-To enable interaction between Arduino and orbiter computer, be sure to [[https://​www.arduino.cc/​en/​guide/​libraries|install]] an interoperability library in Arduino IDE first. The library can be found in the Required Software section. 
-</​note>​ 
- 
-<file c ArduinoTestLed_1_Ard.ino>​ 
-#include <​OrbicraftBus.h>​ // Import the Orbicraft Construction Set control library 
- 
-/* 
-  * Declare the msg variable as the Message data type 
-  * Message comprises a structure that contains IDs and transferred message content 
-*/ 
-Message msg; 
- 
-/* 
-  * Declare the bus variable as the OrbicraftBus data type  
-  * OrbicraftBus is a class describing interaction between Arduino and Orbicraft construction set bus 
-*/ 
-OrbicraftBus bus; 
- 
-// Declare the msgSize variable to hold the size of the received message 
-uint16_t msgSize = 0; 
- 
-void setup() { 
-  Serial1.begin(9600);​ // Define data transfer rate over Serial1 (Check Serial2.begin(9600)) 
-} 
- 
-void loop() { 
-  msgSize = bus.takeMessage(msg);​ // Try to read the message using the takeMessage method 
-  if (msgSize > 0){ //If there is a message… 
-    switch (msg.id){//​Process in a particular manner depending on message ID 
- 
-      // Рассмотрим случай с идентификатором 1 
-        case 0x01: 
-          turnOnLed();​ // Вызов функции для включения и выключения светодиода 
-          break; 
-    }          
-  } 
-} 
- 
-void turnOnLed(void){ 
-  digitalWrite(LED_BUILTIN,​ HIGH); //​Включаем встроенный светодиод 
-  delay(3000);​ //Ждем 3 секунды 
-  digitalWrite (LED_BUILTIN,​ LOW); //​Выключаем встроенный светодиод 
-} 
- 
-/* 
- * Следующий блок кода необходимо всегда добавлять в конец программы 
- * Функция вызывается автоматически и необходима для обработки сообщения 
-*/  
-void serialEvent2() { 
-  bus.serialEventProcess();​ 
-} 
-</​file>​ 
- 
- 
-=====Получение данных от Arduino===== 
- 
-Получение данных от Arduino к БКУ осуществляется с помощью той же функции на стороне БКУ: 
- 
-<code c> 
-int arduino_send(const uint16_t num, const uint16_t msg_id, char *args, char *answer) 
-</​code>​ 
- 
-Суть работы та же, что и при передаче команда с БКУ на Arduino. Используются для работы лишь другие аргументы функции //​arduino_send//​ и соответственно нужно еще сформировать данные для передачи на стороне Arduino. Для примера будем принимать значения с фоторезистора (датчик освещенности),​ подключенного к пину **A0** Arduino. Примеры кода с пояснениями представлены ниже. 
- 
-<note important>​ 
-Прежде чем подключать фоторезистор к Arduino, посмотрите как это правильно делается. Фоторезистор может быть использован в виде отдельного элемента с необходимой периферией,​ а может быть в виде готового модуля с готовой обвязкой. 
-</​note>​ 
- 
-====Код для бортового компьютера==== 
- 
-<file c ArduinoTestLightSensor_1_Orbi.c>​ 
-#include "​libschsat.h"​ 
- 
- void control(void) 
- { 
- char answer[255];​ // Создаем массив для сохранения ответа 
- int32_t count = 5; // Устанавливаем счетчик на 5 шагов 
-/*  
- * Передадим команду на получение ответа с идентификатором 2 на Arduino, используя встроенную функцию arduino_send 
- * Первый аргумент - номер Arduino (по умолчанию 0) 
-        * Второй аргумент - идентификатор сообщения (в данном случае 2) 
-        * Третий аргумент - передаваемые данные (в данном случае NULL - данных для передачи нет) 
-        * Четвертый аргумент - буфер для получаемых данных ​ (в данном случае answer - массив для сохранения полученных данных) 
- * Пятый аргумент - время ожидания ответа от Arduino в мс (в данном случае 100 мс) 
- */ 
- while (count > 0){ 
- int status = arduino_send(0,​ 2, NULL, answer, 100); 
- if (status == 0){ 
- printf("​Answer:​ %s\r\n",​ answer); 
- } 
- else{ 
- printf("​Error\r\n"​);​ 
- } 
- mSleep(500);​ 
- count--; 
- } 
-  
- } 
-</​file>​ 
- 
-====Код для Arduino==== 
- 
-<file c ArduinoLightSensor_1_Ard.ino>​ 
-#include <​OrbicraftBus.h>​ 
- 
-/* 
-  * Объявим переменную msg как тип данных Message 
-  * Message - представляет собой структуру,​ описывающую идентификаторы передаваемого сообщения 
-*/ 
-Message msg; 
-  
-/* 
-  * Объявим переменную bus как тип данных OrbicraftBus ​ 
-  * OrbicraftBus - представляет собой класс, описывающий взаимодействие Arduino и шины конструктора Orbicraft 
-*/ 
-OrbicraftBus bus; 
-  
-// Объявим переменную msgSize, в которую будет записываться передаваемое сообщение 
-int16_t msgSize = 0; 
-// Объявим номер пина для считывания показаний 
-int data_pin = A0; // Указываем пин, с которого будем считывать показания датчика 
-  
-void setup() { 
-  Serial1.begin(9600);​ // задаем скорость обмена информацией по Serial1 !!! (проверить Serial2.begin(9600)) 
-} 
-  
-void loop() { 
- 
-  msgSize = bus.takeMessage(msg);​ // пробуем прочитать сообщение с помощью метода takeMessage 
-  ​ 
-  if (msgSize > 0){ //если сообщение есть 
-    switch (msg.id){//​в зависимости от идентификатора сообщения выполняем те или иные действия 
-  
-      // Рассмотрим случай с идентификатором 2 
-        case 0x02:{ 
-        String data = String(Sensor_data());​ // записываем показания,​ полученные от функции Sensor_data() в переменную data 
-        bus.sendMessage(bus.obcAddress,​ 0, data); // передаем содержимое переменной data на БКУ 
-        break; 
-      } 
-    } 
-  } 
-} 
-  
-uint16_t Sensor_data(void){ 
-  uint16_t data = analogRead(data_pin);​ //​Считываем показания освещенности с датчика 
-  return data; 
-} 
-  
-/* 
- * Следующий блок кода необходимо всегда добавлять в конец программы 
- * Функция вызывается автоматически и необходима для обработки сообщения 
-*/  
-void serialEvent2() { 
-  bus.serialEventProcess();​ 
-} 
-</​file>​ 
en/arduino_module_base_lesson.txt · Last modified: 2020/03/25 16:28 (external edit)