BLE connection works
This commit is contained in:
parent
4514cde473
commit
0b141290b4
104
teng/address.hpp
104
teng/address.hpp
@ -1,104 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
class Counter {
|
||||
public:
|
||||
const unsigned MAX_NUMBER = 4096; // 12-bit
|
||||
const int RES = 18;
|
||||
const int CB = 19;
|
||||
void reset() {
|
||||
digitalWrite(CB, HIGH);
|
||||
digitalWrite(RES, HIGH);
|
||||
delay(1);
|
||||
digitalWrite(RES, LOW);
|
||||
currentValue = 0;
|
||||
}
|
||||
/**
|
||||
* @brief Increment the counter value
|
||||
* @returns true if overflown to zero
|
||||
*/
|
||||
bool increment() {
|
||||
digitalWrite(CB, LOW);
|
||||
delay(1);
|
||||
digitalWrite(CB, HIGH);
|
||||
currentValue++;
|
||||
if (currentValue >= MAX_NUMBER) {
|
||||
currentValue = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
unsigned get() { return currentValue; }
|
||||
private:
|
||||
unsigned currentValue = 0;
|
||||
};
|
||||
|
||||
class AddressState {
|
||||
public:
|
||||
AddressState(Counter counter_, int addressPinCount_, const int* addressPins_)
|
||||
: counter(counter_), addressPinCount(addressPinCount_), addressPins(addressPins_) {
|
||||
counter.reset();
|
||||
}
|
||||
void set(unsigned targetAddress) {
|
||||
unsigned targetCounterValue = targetAddress % counter.MAX_NUMBER;
|
||||
if (counter.get() > targetCounterValue) {
|
||||
counter.reset();
|
||||
|
||||
}
|
||||
for (unsigned i = 0; i < (targetCounterValue - counter.get()); i++) {
|
||||
counter.increment();
|
||||
}
|
||||
|
||||
unsigned pinValues = targetAddress / counter.MAX_NUMBER;
|
||||
addressPinStateMask = 0;
|
||||
for (unsigned i = 0; i < addressPinCount; i++) {
|
||||
unsigned bitSet = pinValues & (1 << i);
|
||||
if (bitSet > 0) {
|
||||
digitalWrite(addressPins[i], HIGH);
|
||||
addressPinStateMask |= (1 << (addressPins[i] - 1));
|
||||
}
|
||||
else {
|
||||
digitalWrite(addressPins[i], LOW);
|
||||
|
||||
}
|
||||
}
|
||||
address = targetAddress;
|
||||
}
|
||||
|
||||
|
||||
void increment() {
|
||||
if (counter.increment()) { // if overflow
|
||||
// add 1 to the other pins
|
||||
for (unsigned i = 0; i < addressPinCount; i++) {
|
||||
if ((addressPinStateMask & (addressPins[i] - 1)) == 0) {
|
||||
addressPinStateMask |= (1 << (addressPins[i] - 1));
|
||||
digitalWrite(addressPins[i], HIGH);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
addressPinStateMask ^= (1 << (addressPins[i] - 1));
|
||||
digitalWrite(addressPins[i], LOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
address++;
|
||||
}
|
||||
|
||||
|
||||
unsigned getAddress() { return address; }
|
||||
unsigned reset() {
|
||||
counter.reset();
|
||||
for (unsigned i = 0; i < addressPinCount; i++) {
|
||||
digitalWrite(addressPins[i], LOW);
|
||||
}
|
||||
}
|
||||
private:
|
||||
// if counter is 12 bit and address is 16 bit, this is the value of the top 4 bits
|
||||
// i-th bit represents i-th pin
|
||||
unsigned addressPinStateMask = 0;
|
||||
unsigned address = 0;
|
||||
Counter counter;
|
||||
const int* addressPins;
|
||||
int addressPinCount;
|
||||
};
|
@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
const char CTRL_WRITE = 1;
|
||||
const char CTRL_READ = 2;
|
||||
const char CTRL_256KB = 11;
|
||||
const char CTRL_2M = 14;
|
@ -1,70 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "address.hpp"
|
||||
|
||||
class EEPROM {
|
||||
public:
|
||||
void setup() {
|
||||
for (unsigned i = 0; i < addressPinCount; i++) {
|
||||
pinMode(addressPins[i], OUTPUT);
|
||||
}
|
||||
for (unsigned i = 0; i < 8; i++) {
|
||||
pinMode(dataPins[i], INPUT);
|
||||
}
|
||||
pinMode(OEb, OUTPUT);
|
||||
pinMode(WEb, OUTPUT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the data pins.
|
||||
*/
|
||||
uint8_t readDataPins() {
|
||||
uint8_t b = 0;
|
||||
for (unsigned i = 0; i < 8; i++) {
|
||||
b |= (digitalRead(dataPins[i]) << i);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
// set start address in via AddressState
|
||||
void read(uint8_t* data, unsigned dataSize, AddressState& address) {
|
||||
unsigned i = 0;
|
||||
for (unsigned i = 0; i < dataSize; i++) {
|
||||
digitalWrite(OEb, LOW);
|
||||
delay(t_OUTPUT_DELAY);
|
||||
data[i] = readDataPins();
|
||||
digitalWrite(OEb, HIGH);
|
||||
delay(t_OUTPUT_FLOAT);
|
||||
address.increment();
|
||||
}
|
||||
}
|
||||
|
||||
/* private: */
|
||||
int OEb;
|
||||
int WEb;
|
||||
int addressPins[6];
|
||||
unsigned addressPinCount;
|
||||
int dataPins[8] = { 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
|
||||
// in ms
|
||||
unsigned t_OUTPUT_DELAY = 1;
|
||||
unsigned t_MIN_WRITE_PULSE_WIDTH = 1;
|
||||
unsigned t_OUTPUT_FLOAT = 1;
|
||||
unsigned t_DATA_HOLD_TIME = 0;
|
||||
};
|
||||
|
||||
constexpr EEPROM AT28C256 {
|
||||
.OEb = 17,
|
||||
.WEb = 16,
|
||||
.addressPins = {10, 15, 11},
|
||||
.addressPinCount = 3
|
||||
};
|
||||
|
||||
constexpr EEPROM SST39SF02A {
|
||||
.OEb = 17,
|
||||
.WEb = 16,
|
||||
.addressPins = {10, 15, 16, 11, 12, 14},
|
||||
.addressPinCount = 6
|
||||
};
|
@ -1,23 +0,0 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
enum PacketType : uint8_t {
|
||||
MESSAGE, STATUS, COMMAND
|
||||
};
|
||||
|
||||
struct Packet {
|
||||
public:
|
||||
using size_type = uint16_t;
|
||||
Packet(PacketType type, size_type size)
|
||||
: type(type), size(size) {
|
||||
payload = new uint8_t[size];
|
||||
}
|
||||
~Packet() {
|
||||
delete[] payload;
|
||||
}
|
||||
uint8_t type;
|
||||
size_type size;
|
||||
uint8_t* payload;
|
||||
|
||||
};
|
17
teng/services.hpp
Normal file
17
teng/services.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoBLE.h>
|
||||
|
||||
const char* BASE_UUID = "00000000-9a74-4b30-9361-4a16ec09930f";
|
||||
|
||||
// Service 1: TENG
|
||||
const char* TENG_SUUID = "00010000-9a74-4b30-9361-4a16ec09930f"; // Service UUID
|
||||
const char* TENG_STATUS_CUUID = "00010001-9a74-4b30-9361-4a16ec09930f"; // Characteristic UUID
|
||||
const char* TENG_COMMAND_CUUID = "00010002-9a74-4b30-9361-4a16ec09930f"; // Characteristic UUID
|
||||
const char* TENG_READING_CUUID = "00010003-9a74-4b30-9361-4a16ec09930f"; // Characteristic UUID
|
||||
BLEService tengService(TENG_SUUID);
|
||||
BLEByteCharacteristic tengStatus(TENG_STATUS_CUUID, BLERead | BLENotify);
|
||||
BLEByteCharacteristic tengCommand(TENG_COMMAND_CUUID, BLEWrite);
|
||||
BLEUnsignedShortCharacteristic tengReading(TENG_READING_CUUID, BLERead);
|
||||
|
||||
enum Command : byte { NOOP = 0, MEASURE_BASELINE }
|
6
teng/settings.hpp
Normal file
6
teng/settings.hpp
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
constexpr int LED_RED = 2;
|
||||
constexpr int LED_YELLOW = 3;
|
||||
constexpr int LED_GREEN = 4;
|
||||
constexpr int PIN_TENG = 0;
|
37
teng/status.hpp
Normal file
37
teng/status.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "settings.hpp"
|
||||
#include "services.hpp"
|
||||
|
||||
// needs to be in separate file because sketch preprocessor reorders stuff
|
||||
enum DeviceStatus : uint8_t { ERROR = 0, BUSY, WAIT_CONNECT, MEASURING_BASELINE, READING };
|
||||
|
||||
void setStatusLED(DeviceStatus s, bool value) {
|
||||
switch (s) {
|
||||
case ERROR:
|
||||
digitalWrite(LED_RED, value);
|
||||
break;
|
||||
case BUSY:
|
||||
digitalWrite(LED_YELLOW, value);
|
||||
break;
|
||||
case WAIT_CONNECT:
|
||||
digitalWrite(LED_YELLOW, value);
|
||||
digitalWrite(LED_GREEN, value);
|
||||
break;
|
||||
case MEASURING_BASELINE:
|
||||
digitalWrite(LED_YELLOW, value);
|
||||
digitalWrite(LED_RED, value);
|
||||
break;
|
||||
case READING:
|
||||
digitalWrite(LED_GREEN, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
DeviceStatus deviceStatus = WAIT_CONNECT;
|
||||
void setStatus(DeviceStatus s) {
|
||||
setStatusLED(deviceStatus, LOW);
|
||||
setStatusLED(s, HIGH);
|
||||
deviceStatus = s;
|
||||
tengStatus.writeValue(deviceStatus);
|
||||
}
|
128
teng/teng.ino
128
teng/teng.ino
@ -1,31 +1,14 @@
|
||||
/*
|
||||
* EEPROM PROGRAMMER
|
||||
* 15-18 Address Pins
|
||||
* 8 Data Pins
|
||||
* 2 Control Pins (OEb, WEb)
|
||||
*
|
||||
* CEb must tied to ground
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <ArduinoBLE.h>
|
||||
/* #include "eeprom.hpp" */
|
||||
/* #include "address.hpp" */
|
||||
|
||||
/* #include "control_bytes.hpp" */
|
||||
#include "settings.hpp"
|
||||
#include "status.hpp"
|
||||
#include "services.hpp"
|
||||
|
||||
constexpr int LED_RED = 2;
|
||||
constexpr int LED_YELLOW = 3;
|
||||
constexpr int LED_GREEN = 4;
|
||||
constexpr int PIN_TENG = 0;
|
||||
|
||||
/* void maskedWrite(uint32_t mask, uint32_t bits) { */
|
||||
/* for (uint32_t i = 0; i < 32; i++) { */
|
||||
/* if (mask & (1 << i)) { */
|
||||
/* digitalWrite(i, bits & (1 << i)); */
|
||||
/* } */
|
||||
/* } */
|
||||
/* } */
|
||||
void blinkLED(unsigned n=5, unsigned delay_=200) {
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
@ -36,6 +19,7 @@ void blinkLED(unsigned n=5, unsigned delay_=200) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned MAX_DEVIATION = 0;
|
||||
unsigned BASELINE = 0;
|
||||
void measureBaseline(unsigned nMeas, unsigned interval=50) {
|
||||
@ -58,49 +42,38 @@ void measureBaseline(unsigned nMeas, unsigned interval=50) {
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
/* pinMode(LED_BUILTIN, OUTPUT); */
|
||||
/* digitalWrite(LED_BUILTIN, HIGH); */
|
||||
/* delay(200); */
|
||||
|
||||
void setup() {
|
||||
setStatus(DeviceStatus::BUSY);
|
||||
Serial.begin(9600);
|
||||
/* // wait until available */
|
||||
while (!Serial);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
delay(200); // empty buffer
|
||||
while (Serial.read() != -1);
|
||||
/* while (!Serial); */
|
||||
|
||||
/* digitalWrite(LED_BUILTIN, HIGH); */
|
||||
/* delay(5000); */
|
||||
blinkLED(2);
|
||||
|
||||
/* // reset counter */
|
||||
/* blinkLED(); */
|
||||
|
||||
/* uint8_t payload[] = { 1, 2, 3, 4, 5, 69 }; */
|
||||
/* uint8_t type = '#'; */
|
||||
/* static_assert(sizeof(payload) == 6); */
|
||||
/* uint16_t size = sizeof(payload); */
|
||||
/* Serial.write(type); */
|
||||
/* Serial.write(lowByte(size)); */
|
||||
/* Serial.write(highByte(size));u */
|
||||
/* Serial.write(payload, size); */
|
||||
|
||||
/* delay(5000); */
|
||||
blinkLED(4);
|
||||
if (!BLE.begin()) {
|
||||
Serial.println("starting Bluetooth® Low Energy module failed!");
|
||||
setStatus(DeviceStatus::ERROR);
|
||||
while(true);
|
||||
}
|
||||
BLE.setDeviceName("ArduinoTeng");
|
||||
/* BLE.setDeviceName("ArduinoTENG"); */
|
||||
BLE.setLocalName("ArduinoTENG");
|
||||
|
||||
byte data[10] = "\xFF\xFFMQU@TUM"; // 0xFFFF manufacturer id for testing
|
||||
BLE.setManufacturerData(data, 10);
|
||||
|
||||
tengService.addCharacteristic(tengStatus);
|
||||
tengService.addCharacteristic(tengCommand);
|
||||
tengService.addCharacteristic(tengReading);
|
||||
|
||||
BLE.addService(tengService);
|
||||
BLE.setAdvertisedService(tengService);
|
||||
|
||||
BLE.setConnectable(true);
|
||||
blinkLED(3);
|
||||
BLE.advertise();
|
||||
|
||||
measureBaseline(100);
|
||||
digitalWrite(LED_RED, HIGH);
|
||||
digitalWrite(LED_YELLOW, HIGH);
|
||||
digitalWrite(LED_GREEN, HIGH);
|
||||
delay(500);
|
||||
digitalWrite(LED_RED, LOW);
|
||||
digitalWrite(LED_YELLOW, LOW);
|
||||
digitalWrite(LED_GREEN, LOW);
|
||||
setStatus(DeviceStatus::WAIT_CONNECT);
|
||||
}
|
||||
|
||||
|
||||
@ -109,6 +82,53 @@ void setup() {
|
||||
|
||||
// the loop function runs over and over again forever
|
||||
void loop() {
|
||||
blinkLED(3, 100);
|
||||
// listen for Bluetooth® Low Energy peripherals to connect:
|
||||
BLEDevice central = BLE.central();
|
||||
|
||||
// if a central is connected to peripheral:
|
||||
if (central) {
|
||||
setStatus(DeviceStatus::READING);
|
||||
Serial.print("Connected to central: ");
|
||||
Serial.println(central.address());
|
||||
|
||||
while (central.connected()) {
|
||||
if (tengCommand.written()) {
|
||||
switch (tengCommand.value()) {
|
||||
case Command::NOOP:
|
||||
setStatus(DeviceStatus::BUSY);
|
||||
delay(1000);
|
||||
break;
|
||||
case Command::MEASURE_BASELINE:
|
||||
setStatus(DeviceStatus::MEASURING_BASELINE);
|
||||
measureBaseline(100);
|
||||
break;
|
||||
default:
|
||||
setStatus(DeviceStatus::ERROR);
|
||||
delay(1000);
|
||||
break;
|
||||
}
|
||||
setStatus(DeviceStatus::READING);
|
||||
}
|
||||
int val = analogRead(PIN_TENG);
|
||||
tengReading.writeValue(static_cast<uint16_t>(val));
|
||||
Serial.print(val, DEC);
|
||||
val -= BASELINE;
|
||||
if (val < 0) { val = -val; }
|
||||
Serial.print("/");
|
||||
Serial.println(val, DEC);
|
||||
delay(300);
|
||||
}
|
||||
setStatus(DeviceStatus::WAIT_CONNECT);
|
||||
// when the central disconnects, notify the user
|
||||
Serial.print("Disconnected from central MAC: ");
|
||||
Serial.println(central.address());
|
||||
}
|
||||
else {
|
||||
BLE.advertise();
|
||||
}
|
||||
return;
|
||||
|
||||
int led_red = LOW;
|
||||
int led_yellow = LOW;
|
||||
int led_green = LOW;
|
||||
@ -145,7 +165,7 @@ void loop() {
|
||||
/* if (mem_size = CTRL_2M) { */
|
||||
/* eeprom = SST39SF02A; */
|
||||
/* } */
|
||||
/* AddressState address(Counter(), eeprom.addressPinCount, eeprom.addressPins); */
|
||||
/* AddressStatus address(Counter(), eeprom.addressPinCount, eeprom.addressPins); */
|
||||
/* const int dataSize = 0x8000; */
|
||||
/* uint8_t data[dataSize]; */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user