Рис.14. Схема электрических соединений микроконтроллера ATmega 328P-PU и платы Arduino UNO для прошивки загрузчика

Рис.15. Схема электрических соединений для загрузки скетча в ATmega 328P-PU

На основе ATmega 328P-PU нами был разработан прибор измерения АГМ №3 (рис. 16, 17).

Рис.16. Автономный прибор №3 со световой индикацией 10-ти уровней АГМ на основе микроконтроллера ATmega 328P-PU, Bluetooth-модуля HC-05 и светодиодной шкалы

Рис.17. Схема электрических соединений прибора №3

Для увеличения компактности и простоты сборки, а также точности измерения АГМ нами был разработан прибор №4, основанный на микроконтроллере ATmega 328P-PU и OLED-дисплее (рис. 18, 19). При этом значительно упростился и скетч (рис. 20).

Рис.18. Автономный прибор №4 с секундомером и цифровой индикацией АГМ повышенной точности на основе микроконтроллера ATmega 328P-PU, Bluetooth-модуля HC-05 и OLED-дисплея

Рис.19. Схема электрических соединений прибора №4

// ПРИБОР ДЛЯ ИЗМЕРЕНИЯ НЕЙРОАКТИВНОСТИ ГОЛОВНОГО МОЗГА

// НА ОCНОВЕ НЕЙРОГАРНИТУРЫ NEUROSKY MINDWAVE MOBILE,

// МИКРОКОНТРОЛЛЕРА ATMEGA 328P-PU, OLED-ДИСПЛЕЯ И БЛЮТУЗ-МОДУЛЯ

// HC-05

// Соединение блютуз-модуля с выводами ATMEGA 328P-PU:

// VCC – VCC

// GND – GND

// TXD – RX

#include <OLED_I2C. h> // Подключаем библиотеку Oled-дисплея

OLED  myOLED(SDA, SCL, 8);

extern uint8_t MediumNumbers[]; // Подключаем средние цифры

extern uint8_t SmallFont[]; // Подключаем малый шрифт

// Определяем порты:

#define LED 13 // подключения контрольного светодиода – индикатора отсутствия шумов

НЕ нашли? Не то? Что вы ищете?

  // при связи с MINDWAVE MOBILE

#define DEBUGOUTPUT 0 // отладки

// Инициализируем переменные контрольной суммы передаваемых данных

byte generatedChecksum = 0;

byte checksum = 0;

// длины полезной нагрузки передаваемых данных

int payloadLength = 0;

byte payloadData[64] = {0};

// уровня шума (помех)

byte poorQuality = 0;

// уровня нейросигнала (концентрации внимания)

byte attention = 0;

// // уровня нейросигнала (расслабления)

byte meditation = 0;

// Инициализируем переменные пакета передачи данных

long lastReceivedPacket = 0;

boolean bigPacket = false;

// Настройки

void setup() {

  myOLED. begin(); // инициализируем Oled-дисплей

  // Определяем подключение контрольного светодиода как порт вывода

  pinMode(LED, OUTPUT);

  // Настраиваем последовательный порт на передачу данных

  Serial. begin(57600); //

}

// Читаем данные (байты) из последовательного порта

  byte ReadOneByte() {

  int ByteRead;

  while(!Serial. available());

  ByteRead = Serial. read();

  #if DEBUGOUTPUT 

  Serial. print((char)ByteRead); // эхо того же байта из последовательного порта (для отладки)

  #endif

  return ByteRead;

}

// Бесконечный цикл

void loop() {

  // Ищем байты синхронизации

  if(ReadOneByte() == 170) {

  if(ReadOneByte() == 170) {

  payloadLength = ReadOneByte();

  if(payloadLength > 169) // длина полезной нагрузки не может быть больше 169

  return;

  generatedChecksum = 0;

  for(int i = 0; i < payloadLength; i++) {

  payloadData[i] = ReadOneByte();  // cчитываем длину полезной нагрузки в память

  generatedChecksum += payloadData[i];

  } 

  checksum = ReadOneByte(); // cчитываем контрольную сумму байта из потока

  generatedChecksum = 255 - generatedChecksum; // возвращаем значение сгенерированной

  // контрольной суммы

  if(checksum == generatedChecksum) {

  poorQuality = 200;

  attention = 0;

  meditation = 0;

  for(int i = 0; i < payloadLength; i++) { // обрабатываем полезную нагрузку

  switch (payloadData[i]) {

  case 2:

  i++;

  poorQuality = payloadData[i];

  bigPacket = true;

  break;

  case 4:

  i++;

  attention = payloadData[i];

  break;

  case 5:

  i++;

  meditation = payloadData[i];

  break;

  case 0x80:

  i = i + 3;

  break;

  case 0x83:

  i = i + 25;

  break;

  default:

  break;

  } // switch

  } // for loop

  #if! DEBUGOUTPUT // Если это не эхо

  // Код индикации внимания и расслабления

  // если пакет данных получен

  if(bigPacket) {

  // если уровень помех нулевой

  if(poorQuality == 0)

  digitalWrite(LED, HIGH); // зажигаем контрольный светодиод

  else

  // иначе гасим

  digitalWrite(LED, LOW);

  // отображаем на мониторе последовательного порта:

  // уровень помех

  Serial. print("PoorQuality: ");

  Serial. print(poorQuality, DEC);

  // уровень концентрации внимания

  Serial. print(" Attention: ");

  Serial. print(attention, DEC);

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

  Serial. print(" Time since last packet: ");

  Serial. print(millis() - lastReceivedPacket, DEC);

  lastReceivedPacket = millis();

  Serial. print("\n");

  // отображаем на Oled-дисплее:

  myOLED. clrScr(); // очищаем экран

  myOLED. setFont(SmallFont);  // устанавливаем малый шрифт

  myOLED. print(" Stopwatch: ", CENTER, 5); // отображаем надпись "Секундомер:"

  myOLED. setFont(MediumNumbers); // устанавливаем средние цифры

  myOLED. printNumI(millis()/1000, CENTER, 15); // отображаем секунды

  myOLED. setFont(SmallFont);  // устанавливаем малый шрифт

  myOLED. print(" Attention: ", CENTER, 35); // отображаем надпись "Внимание:"

  myOLED. setFont(MediumNumbers); // устанавливаем средние цифры

  myOLED. printNumI(attention, CENTER, 45); // отображаем уровень концентрации внимания

  myOLED. update(); // обновляем буфер Oled-дисплея

  }

  #endif

  bigPacket = false;

  }

  else {

  // Ошибка контрольной суммы

  }  // end if else для контрольной суммы

  } // end if read 0xAA byte

  } // end if read 0xAA byte

}

Рис.20. Листинг скетча, обеспечивающего работу прибора №4

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4