Уроки програмування Ардуіно

Уроки програмування Ардуіно

В уроці розповідається, як працювати з внутрішнім EEPROM плати Ардуіно, про контроль цілісності даних при зберіганні і передачі.

Внутрішнє EEPROM в системі Ардуіно.

EEPROM це незалежна пам'ять. Розшифровується як електрично стирається програмований постійний запам'ятовуючий пристрій. Застосовується для зберігання даних, які повинні бути збережені при виключенні живлення.

Плати Ардуіно мають EEPROM різних обсягів залежно від типу використовуваного мікроконтролера.

Обсяг внутрішнього EEPROM

Такого обсягу пам'яті цілком достатньо для зберігання режимів, технологічних параметрів, коефіцієнтів і т.п.

  • Принцип дії EEPROM заснований на створенні електричного заряду в діелектрику напівпровідникової структури. Заряди вічно не зберігаються, але розробники гарантують 20 років.
  • EEPROM має обмежене число циклів запису, як правило, не менше 100 000.
  • Для запису інформації в EEPROM потрібно досить великий час, близько 3 мс.
  • Читання EEPROM відбувається без затримки і ресурс роботи пам'яті не зменшує.

Для роботи з енергонезалежною пам'яттю в Ардуіно є бібліотека EEPROM. Вона має дві функції для запису і читанні байта в EEPROM.

byte read (int address)

void write (int address, byte value)

Програма перевірки запису в EEPROM.

Давайте напишемо просту програму перевірки роботи EEPROM. Програма повинна записувати до 16ти символів, прийнятих з послідовного порту і в циклі виводити 16 символів, лічених з EEPROM. За допомогою монітора порту Arduino IDE ми зможемо записувати дані в EEPROM і контролювати вміст незалежній пам'яті.

// перевірка роботи EEPROM
#include
int i, d;

void setup ()
Serial.begin (9600); // инициализируем порт, швидкості 9600
>

void loop ()
// читання EEPROM і висновок 16 даних в послідовний порт
Serial.println ();
Serial.print ( "EEPROM =");
i = 0; while (i <16)
Serial.print ((char) EEPROM.read (i));
i ++;
>

// перевірка чи є дані для запису
if (Serial.available ()! = 0)
delay (50); // очікування закінчення прийому даних

Завантажуємо програму в плату Ардуіно, перевіряємо. Відкриваємо монітор порту, посилаємо дані на плату: "Перевірка EEPROM".

Уроки програмування Ардуіно
Дані записуються в EEPROM і тепер в циклі виводяться у вікні монітора. Якщо ми відключимо плату від комп'ютера і потім знову підключимо, то дані будуть продовжувати посилати на комп'ютер. Вони збережені в енергонезалежній пам'яті і при виключенні живлення плати не змінюються.

Контроль цілісності даних.

У EEPROM зазвичай зберігають дані абсолютно необхідні для роботи програми. Наприклад, якщо ви робите регулятор температури, то це може бути. задана температура, коефіцієнти регуляторів, параметри захисних функцій і т.п. Уявіть, що ці параметри будуть зіпсовані, а регулятор продовжить роботу. Він може включити нагрівальний елемент на повну потужність і виставити неприпустимо високу температуру. При неправильних коефіцієнтах регулятор може "піти в рознос". Перестануть працювати захисні функції. Неприємності будуть великі.

Але ж ситуація, коли в EEPROM можуть виявитися недостовірні дані цілком реальна.

  • Під час увімкнення пристрою дані в EEPROM недостовірні. Їх просто ніхто ще не ставив.
  • У момент запису даних в EEPROM може відключитися харчування плати і тоді частина даних запишеться, а частина не встигне.
  • EEPROM має обмежене число циклів запису, і це властивість також може привести до руйнування даних в цій пам'яті.

Тому вкрай важливо бути впевненими, що в EEPROM зберігаються достовірні дані. У разі, якщо вони помилкові, програма повинна прийняти певні дії. Це може бути:

  • використовувати копію даних з EEPROM;
  • використовувати дані спеціально створені для аварійного режиму;
  • відключити пристрій;
  • сигналізувати про помилку;
  • і багато інших варіантів.

Цілісність даних це показник, того що дані не були змінені при зберіганні, передачі, відображенні і т.п. Цілісність даних може перевірятися в будь-якій ситуації, потенційно небезпечної для руйнування даних. Зазвичай контроль достовірності даних виробляють:

  • У незалежній пам'яті (EEPROM, FLASH, HDD ...).
  • При передачі даних (послідовні інтерфейси, WiFi, GSM, TCP / IP ...).
  • В оперативній пам'яті для особливо важливих даних.
  • Деякі компоненти (наприклад, датчик DS18B20) мають протокол обміну даними з контролем цілісності.

Для контролю цілісності до блоку даних додається контрольний код. Цей код розраховується за певним алгоритмом при запису даних. При перевірці даних код перераховується і порівнюється з кодом, сформованим під час запису. Якщо коди не співпадають - дані помилкові.

Алгоритм розрахунку контрольного коду визначає ймовірність визначення помилки даних. Існує велика кількість алгоритмів формування контрольних кодів: циклічні коди, різні функції хешування. Але найпростішим способом обчислення контрольного коду є контрольна сума.

Просто робиться математична сума всіх байтів блоку даних. Такий алгоритм вимагає мінімуму ресурсів для реалізації, і в той же час дозволяє з досить високою ймовірністю визначити помилкові дані в разі невеликих обсягів інформації. Контрольна сума може бути різною розрядності. У мінімальному варіанті це один байт. В цьому випадку відбувається переповнення результату суми, що зменшує ймовірність виявлення помилок.

Я завжди до обчисленої контрольної сумі застосовую операцію "виключає АБО" з кодом подібним E5h. Це дозволяє виключити вельми ймовірну ситуацію, коли всі дані рівні 0. Сума 0 дорівнює 0. Тому якщо блок даних буде помилково обнулений (а це буває), то проста сума видатків не вирахує цю помилку. А коли контрольна сума для всіх 0 дорівнює E5h, то помилка буде виявлена.

Давайте додамо в попередню програму контроль цілісності даних.

// перевірка роботи EEPROM
#include
int i, d;
byte sum; // контрольна сума

void setup ()
Serial.begin (9600); // инициализируем порт, швидкості 9600
>

void loop ()
// обчислення контрольної суми
sum = 0;
i = 0; while (i <16)
sum + = EEPROM.read (i);
i ++;
>
// перевірка контрольної суми
if ((sum ^ 0xe5) == EEPROM.read (i))
// контрольна сума правильна

// читання EEPROM і висновок 16 даних в послідовний порт
Serial.println ();
Serial.print ( "EEPROM =");
i = 0; while (i <16)
Serial.print ((char) EEPROM.read (i));
i ++;
>
>
else
// контрольна сума неправильна
Serial.println ();
Serial.print ( "EEPROM = data error");
>

// перевірка чи є дані для запису
if (Serial.available ()! = 0)
delay (50); // очікування закінчення прийому даних

// запис в EEPROM
sum = 0;
i = 0; while (i <16)
d = Serial.read ();
if (d == -1) d = ''; // якщо символи закінчилися, заповнення пробілами
EEPROM.write (i, (byte) d); // запис EEPROM
sum + = (byte) d; // обчислення контрольної суми
i ++;
>
EEPROM.write (i, sum ^ 0xe5); // запис контрольної суми
>
delay (500);
>

Зазначу тільки, що програма приймає не 16, а 14 символів, тому що монітор порту додає до кожного рядка символи розриву рядків \ r і \ n.

Завантажимо програму і запустимо монітор.

Уроки програмування Ардуіно

У вікні біжать повідомлення про помилку даних. Ми ще не завантажили в EEPROM ніяких даних, і алгоритм розпізнає цю ситуацію. Пошлемо рядок, наприклад, "перевірка". Тепер у вікні відображаються дані з EEPROM.

Уроки програмування Ардуіно

Таким же чином можна захищати цілісність даних при передачі по послідовному порту. Будь-яка імпульсна перешкода може спотворити сигнал у кабелі зв'язку і викликати помилку даних. Звичайно, програма прийому даних на комп'ютері повинна підтримувати протокол з контрольною сумою. Монітор порту Arduino IDE цієї функції не має.

У наступному уроці дізнаємося, що таке покажчики в C для Ардуіно, навчимося записувати в EEPROM дані різних типів (int, float ...).

E5h це не команда Ассемблера. Це просто число, яке додається до контрольної сумі для виключення ситуації, коли всі дані рівні 0 і контрольна сума дорівнює 0.
Я цитую з уроку:
«Я завжди до обчисленої контрольної сумі застосовую операцію" виключає АБО "з кодом подібним E5h. Це дозволяє виключити вельми ймовірну ситуацію, коли всі дані рівні 0. Сума 0 дорівнює 0. Тому якщо блок даних буде помилково обнулений (а це буває), то проста сума видатків не вирахує цю помилку. А коли контрольна сума для всіх 0 дорівнює E5h, то помилка буде виявлена. »

Хороший спосіб, але є один недолік.
Якщо в програмі допустимо змінюються в налаштуваннях не всі дані, а тільки частину і їх потрібно буде зберігати при виході з меню. А даних наприклад дуже багато. Те потрібно буде кожен раз перераховувати контрольну суму для всіх даних.

Підкажіть, будь ласка, чи правильно я розумію:
- складаючи всі байти вмісту EEPROM в один байт sum, ми цей байт регулярно переповнюють, і
- в деякий, але певний момент sum переходить через 0
- інформація про попередні доданків практично повністю втрачається
- і якщо поміняти місцями два байта на ділянці послідовності між переходами через 0, то
- наша перевірка нічого підозрілого не виявить

це ж вразливість? нехай ймовірність такого події і прагне до нуля ...

Вітаю!
При переповненні байта інформація повністю не втрачається. Байт НЕ обнуляється, а в ньому залишається залишок від суми. Хоча, дійсно, сума не найкращий спосіб формування контрольного коду. Це найпростіший спосіб. Набагато ефективніше використовувати циклічні коди. В уроці 56 я торкаюся цю тему.

Схожі статті