Система автоматического тестирования ВМГ (народный проект)

sulaex

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

Что имеем? Что требуется?
Нам нужно, как минимум получать три показания с датчиков, это ток, напряжение, тяга. Этого минимума будет достаточно для получения результатов и последующего подбора эффективной ВМГ. В дальнейшем можно будет добавить например датчики для снятия показаний КВ, вибрации и т. д.
Не плохо бы использовать для этого ардуину, большинство ею пользуется и имеет в наличии. Но имеется небольшое ограничения при использовании данной платформы, а точнее огромный недостаток, это 10 биттный АЦП, проще говоря вес мы сможем измерять в пределах килограмма. Для измерения тока и напряжения ардуины будет нам вполне достаточно, а вот для измерения тяги придется использовать внешний АЦП. В качестве такого внешнего АЦП предлагаю использовать микросхему ADS1232. Данная микросхема уже имеет усилитель и стоимость у нее не большая, пару баксов всего.

Решение
В даташите АЦП имеется схема подключения к нему тензо-датчика.

На просторах интернета были найдены кусочки кода для чтения данных ардуиной для подобной АЦП.
forum.arduino.cc/index.php/topic,128823.0.html
forum.arduino.cc/index.php?topic=196110.0
Читая ломанный гугло-перевод даташита, добился определенных результатов в чтении данных АЦП с помощью ардуины.

/*
ADS1244

*/

int DATA = 4;
int SCLK = 5;
int PWDN = 3;

void setup() {

pinMode(DATA, INPUT);
pinMode(SCLK, OUTPUT);

Serial.begin(115200);

// generate a 2.4MHz clock signal on pin 3
pinMode(PWDN, OUTPUT); //CLK

// 17.11 Register Description
TCCR2A = 0x33; // 0011 0011
TCCR2B = 0x09; // 0000 1001
OCR2A = 0x06; // 0000 0110
OCR2B = 0x05; // 0000 0011

Serial.print(“ADS1244\n”); // output ‘AADS1244’ (?) additional ‘A’ in front
delay(100);
}

void loop() {

// Code for reading the data:

int32_t value = 0;

digitalWrite(PWDN, HIGH);

//digitalWrite(SCLK, HIGH); //enter slleep mode
delay(300);
digitalWrite(SCLK, LOW); // wake up ADC

// wait for data ready, stay in while-loop until LOW
while (digitalRead(DATA) == HIGH);

value = shiftIn(DATA, SCLK, MSBFIRST);
value <<= 8;
value |= shiftIn(DATA, SCLK, MSBFIRST);
value <<= 8;
value |= shiftIn(DATA, SCLK, MSBFIRST);

digitalWrite(SCLK, HIGH); // enter sleep mode
//digitalWrite(SCLK, LOW); // 25th pulse to keep DATA high till next data ready

// process as int24_t (two’s compliment 24bit)
value = ((signed long) (value << 8)) >> 8;

Serial.println(value, DEC);
Serial.flush();

}

Правильно ли я организовал чтение данных, возможно ли оптимизировать код?
Как я понял, из кода можно выбросить часть с “// generate a 2.4MHz clock signal on pin 3
Завести данный код удалось добавлением “digitalWrite(PWDN, HIGH);
Правильно ли так оставлять его или следует все таки сбрасывать и в какой момент?

Набросал на макетной платке предварительную сборочку стенда.

в качестве датчика тока использую ACS758

для снятия показаний напряжения буду использовать делитель напряжения на резисторах

Rabbit_Fly

какой тензодатчик планируете использовать?

delfin000

Александр, штука эта классная. Без нее долго не полетаешь, если на обум все делать. Но вроде кто-то уже делали подобное. Ну и на всякий случай вот уже готовый вариант hobbyking.com/…/__10487__EagleTree_MicroPower_E_Lo…, правда к электронным весам ее сложно прикрутить, но меряет и обороты, ток, напругу, мощность и еще много чего. Все лагирует с нужным интервалом, далее в своей программе рисует графики… считает сразу мини, макси, среднее и т.д. Любой интервал можно масштабировать, анализировать, обрабатывать отдельно, и также сам интревал записи данных настраиваемый.

sulaex

это не то, похожее устройство имеется в наличии у меня

требуется специализированный стенд
установил ВМГ, крутанул, данные залил в базу

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

ЗЫ в общем то куски кода имеются, все работает
идут данные тяги с внешнего АЦП на ардуину, напряжение и ток меряются
осталось все собрать в кучу, организовать сбор данных, придумать ГУИ
как выше писал, в программировании не в зуб ногой, буду очень благодарен за помощь в дальнейшей разработке ГУИ
собственно я могу данные собирать и через терминал, но было бы лучше организовать интерфейс
если разберусь, возможно и сам, что нить организую, но очень надеюсь на помощь

ЗЫЗЫ по сравнению с STM32 (делал подобный стенд), на много меньше помех по АЦП у ардуины, как я понимаю это связанно с разрядностью?
думаю можно будет использовать данные без цифрового фильтра, это огромный плюс, да и 24 биттный внешний АЦП так же приятно работает без особых помех
очень упрощается программная часть и повышается точность измерений, но это пока догадки, надо собрать все данные в кучу и тогда будет известен результат

delfin000

Но там ведь данные из E-Logger просто ипортируются в Excel (без проблем) и он уже быстро анализирует. Программа в Excel состовляется за час-два во время просмотра телевизора ( анализ маломерных числовых массивов)

Rabbit_Fly
delfin000:

Но там ведь данные из E-Logger просто ипортируются в Excel (без проблем) и он уже быстро анализирует. Программа в Excel состовляется за час-два во время просмотра телевизора ( анализ маломерных числовых массивов)

там нет датчика массы а на нем все и завязанно

delfin000
delfin000:

правда к электронным весам ее сложно прикрутить

но все же возможно по той же I2C 😃 есть еще и аналоговые

sulaex

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

Стоимость собираемого мною стенда будет примерно:
тензодатчик - 10$
АЦП - 3$
ардуина с ФТДИ - 7$ (у большинства она валяется в загашнике)
датчик тока - 5$
обвязка и монтажка ну - 10$
_____________________________
всего 30 баксов относительно легко повторяемый стенд 😃

TeHoTaMy
sulaex:

… имеется небольшое ограничения при использовании данной платформы, а точнее огромный недостаток, это 10 биттный АЦП, проще говоря вес мы сможем измерять в пределах килограмма.

Никакой проблемы на самом деле нет. 10 бит в нашем случае более чем достаточно. Точность измерения составляет 0,1%. Скажем, в диапазоне 0…5кг точность будет плюс-минус 5 грамм. Причем, скорость измерения высокая не требуется, поэтому точность можно повысить многократными измерениями.

sulaex
TeHoTaMy:

Никакой проблемы на самом деле нет. 10 бит в нашем случае более чем достаточно. Точность измерения составляет 0,1%. Скажем, в диапазоне 0…5кг точность будет плюс-минус 5 грамм. Причем, скорость измерения высокая не требуется, поэтому точность можно повысить многократными измерениями.

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

TeHoTaMy
sulaex:

вы не учли шумы внутреннего АЦП, а при использовании фильтра уменьшается точность, если делать несколько замеров, падает скорость теста

Шумы легко фильтруются программным фильтром, а скорость работы внутреннего АЦП на несколько порядков выше, чем требуется для данной задачи.

к тому же микросхема внешнего АЦП стоит столько же, сколько и усилитель для тензодатчика

Подходящий усилитель можно сделать из того, что есть под рукой, а микросхему АЦП в ближайшем магазине можно и не найти.

sulaex
vatanuki:

а что с этой установкой? RThrust - система автоматического тестирования ВМГ вроде тожесамое - единственное что она “закрытая”, а тут будет открытая?

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

TeHoTaMy:

Шумы легко фильтруются программным фильтром, а скорость работы внутреннего АЦП на несколько порядков выше, чем требуется для данной задачи.

Подходящий усилитель можно сделать из того, что есть под рукой, а микросхему АЦП в ближайшем магазине можно и не найти.

на практике знаю возникающие сложности в процессе разработки в данном направлении
имеете реальное предложение, схемы, коды, решения, милости просим, иначе, проходите мимо

по поводу шумов и легкости фильтрации, хотелось бы взглянуть пример вашей легкости решения проблемы
про скорость АЦП, полагаю вы ошиблись в термине, да и не в теме того, что имелось в виду в моем сообщении
ну и на по следок, усилитель, который с легкостью собирается из подручного хлама глянуть бы

sulaex

подбор делителя на шесть банок с запасом

sulaex

пример подбора датчик тока для наших целей

в моем распоряжении имеется датчик ACS758ECB-200B
если мы откроем даташит к этому датчику и посмотрим его данные,
то увидим крайнюю не пригодность данного датчика для наших потребностей,
но на данный момент делать нечего, я буду использовать его.

для правильного подбора датчика требуется воспользоваться таблицей с даташита, посмотрим ее

предположим, что замер тока нашего стенда не будет превышать 50А
датчик тока в моем распоряжении в нулевом состоянии выдает половину опорного напряжения
то есть при нулевом значении АЦП будет выдавать значение 512
причем точность показаний будет 10мВ на 1А - это самое не подходящее значение
для наших целей лучшим датчиком будет ACS758LCB-050U
этот датчик измеряет до 50А с точностью 60мВ/1А, самый точный из ACS758 для наших целей
точность в 6 раз выше используемого мною

обращайте внимание на буковку U в маркировке датчика, этот датчик меряет ток в одном направлении
тем самым точность повышается в два раза

ЗЫ выше описанное является моим пониманием прочтенного, на достоверность не претендую
если есть замечания или исправления, прошу поправить

Gapey

сейчас полез на Али смотреть тензодатчики … первое что бросилосЪ в глаза - куча недорогих готовых модулей АЦП изначально заточеных под тензодатчик - hx711 … ИМХО поддержка таких модулей сильно облегчит повторение конструкции …
датчик имеет смысл брать именно на 10 кг или лучне на 5 ???
еще едут регули , китайская подделка ESC32 … если разобраться с протоколом то с них можно получать напряжение , ток и обороты … только нужен будет свободный компорт (проблему решает ардуина мега или леонардо ) …
тогда получается для стенда нужны будут только ардуина , регуль ESC32 , плата на hx711 и тензодатчик …

sulaex

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

Gapey:

датчик имеет смысл брать именно на 10 кг или лучне на 5 ???

Зависит от ваших потребностей, если вы не собираетесь измерять ВМГ с тягой не превышающей пару килограмм, думаю достаточно тензодатчика и в 3 килограмма, точность измерений будет больше.
Чем больше будет значение, тем меньше будет точность, хотя для АЦП в 24 битта это не особо критично.

Gapey:

тогда получается для стенда нужны будут только ардуина , регуль ESC32 , плата на hx711 и тензодатчик …

пошел искать инфу по этим регулям

ЗЫ добавлено апосля
не, думаю нет смысла включать в проект данный регуль, слишком он дорогой

sulaex

Формула для расчета значения тока датчика с двухсторонним измерением (буква B в маркировке)
I=(Count-CountNull)*(ISensor/512)

Формула для расчета значения тока датчика с односторонним измерением (буква U в маркировке)
I=Count*(ISensor/1024)

I - значение тока (результат)
Count - показания АЦП ардуины
CountNull - показания АЦП без нагрузки (нулевое значение тока)
ISensor - максимальный ток измеряемый датчиком (смотрите в таблице)

по поводу точности датчиков:
для датчика ACS758ECB-200B шаг измерения 200А/512=0.39 А (например для 20А значения всего 50 показаний, маловато)
для датчика ACS758LCB-050U шаг измерения 50А/1024=0.05 А (например для 20А значения 400 показаний, более чем достаточно)

ЗЫ заметка, надо будет завтра попробовать запитать схему стенда от аккумулятора через стабилизатор
добиться идеальных нулевых показаний АЦП путем стабилизации опорного напряжения, что бы исключить общую настройку стенда в целом

Gapey
sulaex:

не, думаю нет смысла включать в проект данный регуль, слишком он дорогой

вы видимо смотрели оригинальную версию которую “из принципа” паяют в европе , ну и цена соответственно 39 евро …
я-же взял на Али подделки , 5 штук по $23,29 фришип , что для 40 амперных регулей вполне нормально …
как приедут , буду сравнивать их эффективность по сравнению с обычными , насколько стоит с ними связываться …

sulaex

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

тяга и ток калибруются в ноль при включении
напряжение и остальные калибровки будут позже

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

//объявление переменных
//подключаемые разьемы на ардуине
int PWM = 3;  //пин D3 для ШИМ
int DATA = 4;  //пин D4 подключаем АЦП тяги
int SCLK = 5;  //пин D5 подключаем АЦП тяги
int PWDN = 6;  //пин D6 подключаем АЦП тяги
#define CurrPin A0  //пин A0 датчик тока
#define VoltPin A1  //пин A1 датчик напряжения
//переменные для работы
float CurrentValue = 0;  //переменная для расчета тока (с плавающей точкой)
float CurrentValueRes = 0;  //переменная с результатом для расчета тока (с плавающей точкой)
float VoltageValue = 0;  //переменная для расчета напряжения (с плавающей точкой)
int32_t Weight = 0;  //переменная для расчета тяги (32 разряда)
//переменные для нулевых значений
int32_t WeightNull = 0; //нулевое значение по весу (переменная калибруется при включении)
int CountNull = 0;  //нулевое значение по току, данная переменная для однонаправленных датчиков ACS758 (с буквой U) не используется (переменная калибруется при включении)

//эти переменные заполняются пользователем
int ISensor = 200;  //максимальное значение измеряемое датчиком (смотрим даташит по ним)

//инициализация
void setup() {
  //инициализация I/O
  pinMode(DATA, INPUT);
  pinMode(SCLK, OUTPUT);
  pinMode(PWDN, OUTPUT);
  digitalWrite(PWDN, HIGH);
  //скорость порта
  Serial.begin(57600);
  //читаем нулевые значения по весу и току
  WeightNull = getSensorValueWeight();
  CountNull = analogRead(CurrPin);
}

//чтение данных тяги
int32_t getSensorValueWeight() {
  digitalWrite(SCLK, LOW);  // wake up ADC
  while (digitalRead(DATA) == HIGH);  // wait for data ready, stay in while-loop until LOW
  Weight = shiftIn(DATA, SCLK, MSBFIRST);
  Weight <<= 8;
  Weight |= shiftIn(DATA, SCLK, MSBFIRST);
  Weight <<= 8;
  Weight |= shiftIn(DATA, SCLK, MSBFIRST);
  digitalWrite(SCLK, HIGH);  // enter sleep mode
  Weight = ((signed long) (Weight << 8)) >> 8;  // process as int24_t (two's compliment 24bit)
  return Weight;
}

//начало работы в цыкле
void loop() {

  Weight = (getSensorValueWeight() - WeightNull)/204.6615;

  //расчет данных напряжения
  VoltageValue = analogRead(VoltPin);  // считываем значение аналогового входа (напряжение)
  VoltageValue = VoltageValue*0.0298217;

  //расчет данных тока
  CurrentValue = analogRead(CurrPin);  // считываем значение аналогового входа (ток)
  CurrentValueRes = (CurrentValue-CountNull)*ISensor/512;  //формула расчета тока для двунаправленнх датчиков ACS758
  //CurrentValueRes = CurrentValue*ISensor/1024;  //формула расчета тока для однонаправленных датчиков ACS758

  //выводим результат
  Serial.print(Weight);
  Serial.print("\t");
  Serial.print(VoltageValue);
  Serial.print("\t");
  Serial.println(CurrentValueRes);

  Serial.flush();

}
sulaex

список линков для закупки комплектующих для создания стенда

как я и писал выше, цель проекта создание стенда для тестирования ВМГ как можно дешевле и проще в повторении
данный проект можно будет повторить в двух вариантах, модульный и одно-платный, а так же смешанном из этих вариантов
модульный является самым простым и доступным к повторению, одно-платный будет предоставлен позже и будет самым дешевым

список модулей (например):

Arduino Mini Pro

основой модульного проекта является плата с процессором, в качестве этой борды возможно использовать любой модуль или готовый контроллер на атмеге
например ардуины UNO, Pro Mini и т. д., так же можно использовать платки полетных контроллеров, Кук, МультиВий, в общем все, в чем имеется атмега (при желании можно и регуль переделать 😃)

линк - www.aliexpress.com/item/…/1242584516.html - 7$
по данному линку модуль продается с FTDI (следующий по списку, не надо будет отдельно покупать)

модуль FTDI

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

линк - www.aliexpress.com/wholesale?SearchText=ftdi&catId… - 7$

готовый модуль АЦП для снятия показаний с тензодатчика

данный модуль организует снятие аналоговых данных с тензодатчика (датчик тяги, датчик веса) и преобразует эти данные в цифровой вид для последующей обработки на ардуине, именно подобный модуль сподвиг меня на поднятие данного проекта, так как разрядности АЦП ардуины было не достаточно для требуемых расчетов (спасибо Юрию за наводку)

линк - www.ebay.com/itm/400563601604 - 7$

датчик тяги

датчик тяги (веса), в большинстве случаев достаточно пяти колограммового, хотя и 10 кг совсем не сколечко не испортит нам данных

линк - www.aliexpress.com/item/…/1192555182.html - 10$

модуль датчика тока

выше в этой теме я уже расписал, какой датчик выбрать лучше

линк - www.ebay.com/itm/111040360152 - 18$
по линку очень дорогой модуль, можно найти на много дешевле

не требуется, но для удобства можно использовать синий зуб

с данным модулем будет удобнее работать и управлять стендом, можно будет установить стенд достаточно далеко и на безопасное расстояние, не обременяя себя кабелем связи
подробности подключения и настройки можно прочитать на этом же форуме в теме rcopen.com/forum/f123/topic261502

sulaex

“летим птичка там много вкусного”

какая прелесть!? 😃

в поисках работы с ШИМ наткнулся на пример связи компьютера и ардуины посредством терминала, а так же среду разработки приложений очень похожую на ардуиновскую
кому интересно, вот линк

SergDoc

Среда эта называется Processing - на её основе как раз и сделана среда Arduino 😃

sulaex
SergDoc:

Среда эта называется Processing - на её основе как раз и сделана среда Arduino 😃

ага, догадался уже 😃

некоторые наработки аля DOS консоль и работа с ШИМ (пока без ремарок)
на видео показана возможность выбора режима теста и прерывание работы теста любой клавишей на случай возникновения аварийной ситуации,
прошу не ругаться за мой английский а поправить его

// добавляем библиотеку для работы с сервоприводами
#include <Servo.h>
// для дальнейшей работы назовем 9 пин как servoPin
#define servoPin 3
// 544 это стандартная длина импульса при котором сервопривод должен принять положение 0°
#define servoMinImp 544
// 2400 это эталонная длина импульса при котором сервопривод должен принять положение 180°
#define servoMaxImp 2400
Servo myServo;

int val;                           //здесь будет храниться принятый символ
int n;
int error = 0;

void setup()
{
myServo.attach(servoPin, servoMinImp, servoMaxImp);
// устанавливаем пин как вывод управления сервоприводом,
// а также для работы сервопривода непосредственно в диапазоне углов от 0 до 180° задаем мин и макс значения импульсов.
// импульсы с большей или меньшей длиной восприниматься не будут.
// для сервоприводов даже одной партии значения длин импульсов могут отличаться, может быть даже и 584-2440.
// поэкспериментируйте и найдите идеальные длины импульсов конкретно для вашего сервопривода.

  Serial.begin(9600);              //установка порта на скорость 9600 бит/сек

  myServo.writeMicroseconds(set_pos(0));
}

//чтение вводимой строки из терминала
String readText(int n){
  int i = 0;
  String str;

  while (i<n) {
	while (!(Serial.available()));
        val = Serial.read();
        if (val==13){return str;}
        Serial.print(char(val));
        str += char(val);
        i++;
  }
  return str;
}

// Функция устанавливает стик газа
int set_pos(int pos) {
  int tmp=(servoMaxImp - servoMinImp) /100;
  pos = servoMinImp + tmp * pos;
  return pos;
}

void beginTest(){
  Serial.println("\n\r============= Select action: =============");
  Serial.println("1 - begin auto test 50, 65, 75, 85, 100%");
  Serial.println("2 - begin auto test 1-100%");
  Serial.println("3 - begin manual test");
  Serial.println("any key - return to console");
  Serial.println("==========================================");
  while (!(Serial.available())); val = Serial.read();
  Serial.print("you select "); Serial.println(char(val));
  if (val==49){test(1);}
  if (val==50){test(2);}
  if (val==51){test(3);}
  Serial.println("\n\r stop test return to console");
  return;
}

int test(int n){
  Serial.println("\n\r============= Select action: =============");
  Serial.println("8 - begin test");
  Serial.println("any key - stop test and return to console");
  Serial.println("==========================================");
  while (!(Serial.available())); val = Serial.read();
  if (val==56){
    Serial.println("you select 8");
    Serial.println("\n\r start test");
    Serial.println();
    if (n==1){
      if (delayM(200)==1){myServo.writeMicroseconds(set_pos(0)); return 0;}
      Serial.println("throtle from 0 to 49%"); for (n=0; n<50; n++){myServo.writeMicroseconds(set_pos(n)); if (delayM(30)==1){myServo.writeMicroseconds(set_pos(0)); return 0;};}
      Serial.println("throtle = 50%"); myServo.writeMicroseconds(set_pos(50)); if (delayM(1000)==1){myServo.writeMicroseconds(set_pos(0)); return 0;}
      Serial.println("throtle = 65%"); myServo.writeMicroseconds(set_pos(65)); if (delayM(1000)==1){myServo.writeMicroseconds(set_pos(0)); return 0;}
      Serial.println("throtle = 75%"); myServo.writeMicroseconds(set_pos(75)); if (delayM(1000)==1){myServo.writeMicroseconds(set_pos(0)); return 0;}
      Serial.println("throtle = 85%"); myServo.writeMicroseconds(set_pos(85)); if (delayM(1000)==1){myServo.writeMicroseconds(set_pos(0)); return 0;}
      Serial.println("throtle = 100%"); myServo.writeMicroseconds(set_pos(100)); if (delayM(1000)==1){myServo.writeMicroseconds(set_pos(0)); return 0;}
      Serial.println("throtle = 0%"); myServo.writeMicroseconds(set_pos(0));
    }
    if (n==2){
      if (delayM(200)==1){myServo.writeMicroseconds(set_pos(0)); return 0;}
      Serial.println("throtle from 0 to 100%"); for (n=0; n<100; n++){myServo.writeMicroseconds(set_pos(n)); if (delayM(50)==1){myServo.writeMicroseconds(set_pos(0)); return 0;};}
      Serial.println("throtle = 0%"); myServo.writeMicroseconds(set_pos(0));
    }
  }
  return 0;
}

int delayM(int m){
  int k;
  for (k=0; k<m; k++){
    if (!(Serial.available())){}else{k = 1; Serial.println("\n\r break"); return k;}
    delay(1);
  }
  k = 0;
  return k;
}

void beginCalibrate(){
  Serial.println("\n\r============= Select action: =============");
  Serial.println("1 - calibration weight");
  Serial.println("2 - calibration voltage");
  Serial.println("3 - calibration curent");
  Serial.println("4 - calibration ESC");
  Serial.println("any key - return to console");
  Serial.println("==========================================");
  while (!(Serial.available())); val = Serial.read();
  if (val==49){Serial.println("\n\r 1 ok");}
  if (val==50){Serial.println("\n\r 2 ok");}
  if (val==51){Serial.println("\n\r 3 ok");}
  if (val==52){Serial.println("\n\r 4 ok");}
  Serial.println("\n\r stop calibration return to console");
  return;
}

void loop()
{
  Serial.println();
  ("Helow my frend!");
  Serial.println("Please type the comands:");
  Serial.println("test, calibration, null, setup");
  Serial.println();
  Serial.print(">");
  while (!(Serial.available()));
  String myString = readText(60);
  if (myString=="test"){Serial.println(); beginTest(); error = 0;}
  if (myString=="setup"){Serial.println("\n\r setup ok"); error = 0;}
  if (myString=="calibration"){Serial.println(); beginCalibrate(); error = 0;}
  if (myString=="null"){Serial.println("\n\r null ok"); error = 0;}
  if (myString==""){Serial.println(); error = 0;}
  if (error==0){error=1;}else{Serial.println("\n\r incorrect command");}
}

ЗЫ видео высокого качества следует установить, что бы видеть текст на экране