BTLE example for a CJMCU-8223 (NRF51822+Lis3dh). Also includes an OLED display. Further details on ioprog.com
Dependencies: mbed BLE_API nRF51822
Revision 0:8fa1c7356f71, committed 2020-06-24
- Comitter:
- f3d
- Date:
- Wed Jun 24 11:37:11 2020 +0000
- Commit message:
- Initial commit for CJMCU-8223 offering an LED service and an accelerometer service. Also includes an Oled display
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BLE_API.lib Wed Jun 24 11:37:11 2020 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/#65474dc93927
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/LEDService.h Wed Jun 24 11:37:11 2020 +0000
@@ -0,0 +1,42 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __BLE_LED_SERVICE_H__
+#define __BLE_LED_SERVICE_H__
+
+class LEDService {
+public:
+ const static uint16_t LED_SERVICE_UUID = 0xA000;
+ const static uint16_t LED_STATE_CHARACTERISTIC_UUID = 0xA001;
+
+ LEDService(BLEDevice &_ble, bool initialValueForLEDCharacteristic) :
+ ble(_ble), ledState(LED_STATE_CHARACTERISTIC_UUID, &initialValueForLEDCharacteristic)
+ {
+ GattCharacteristic *charTable[] = {&ledState};
+ GattService ledService(LED_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+ ble.addService(ledService);
+ }
+
+ GattAttribute::Handle_t getValueHandle() const {
+ return ledState.getValueHandle();
+ }
+
+private:
+ BLEDevice &ble;
+ ReadWriteGattCharacteristic<bool> ledState;
+};
+
+#endif /* #ifndef __BLE_LED_SERVICE_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/accelService.h Wed Jun 24 11:37:11 2020 +0000
@@ -0,0 +1,66 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __BLE_ACCEL_SERVICE_H__
+#define __BLE_ACCEL_SERVICE_H__
+#include <mbed.h>
+#include <lis3dh.h>
+lis3dh Lis3dh;
+class accelService {
+public:
+ const static uint16_t ACCEL_SERVICE_UUID = 0xA012;
+ const static uint16_t ACCEL_X_CHARACTERISTIC_UUID = 0xA013;
+ const static uint16_t ACCEL_Y_CHARACTERISTIC_UUID = 0xA014;
+ const static uint16_t ACCEL_Z_CHARACTERISTIC_UUID = 0xA015;
+
+ accelService(BLEDevice &_ble, int16_t initialValueForACCELCharacteristic) :
+ ble(_ble), AccelX(ACCEL_X_CHARACTERISTIC_UUID, &initialValueForACCELCharacteristic),AccelY(ACCEL_Y_CHARACTERISTIC_UUID, &initialValueForACCELCharacteristic),AccelZ(ACCEL_Z_CHARACTERISTIC_UUID, &initialValueForACCELCharacteristic)
+ {
+ GattCharacteristic *charTable[] = {&AccelX,&AccelY,&AccelZ};
+ GattService AccelService(ACCEL_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+ ble.addService(AccelService);
+ Lis3dh.begin();
+ }
+
+ GattAttribute::Handle_t getValueHandle() const {
+ return AccelX.getValueHandle();
+ }
+ void updateAccelX(uint16_t newValue) {
+ ble.gattServer().write(AccelX.getValueHandle(), (uint8_t *)&newValue, sizeof(uint16_t));
+ }
+ void updateAccelY(uint16_t newValue) {
+ ble.gattServer().write(AccelY.getValueHandle(), (uint8_t *)&newValue, sizeof(uint16_t));
+ }
+ void updateAccelZ(uint16_t newValue) {
+ ble.gattServer().write(AccelZ.getValueHandle(), (uint8_t *)&newValue, sizeof(uint16_t));
+ }
+ void poll()
+ {
+ int X,Y,Z;
+ Lis3dh.read(X,Y,Z);
+ updateAccelX(X);
+ updateAccelY(Y);
+ updateAccelZ(Z);
+
+ }
+private:
+ BLEDevice &ble;
+ ReadOnlyGattCharacteristic<int16_t> AccelX;
+ ReadOnlyGattCharacteristic<int16_t> AccelY;
+ ReadOnlyGattCharacteristic<int16_t> AccelZ;
+};
+
+#endif /* #ifndef __BLE_ACCEL_SERVICE_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/font5x7.h Wed Jun 24 11:37:11 2020 +0000
@@ -0,0 +1,125 @@
+/*! \file font5x7.h \brief Graphic LCD Font (Ascii Characters). */
+//*****************************************************************************
+//
+// File Name : 'font5x7.h'
+// Title : Graphic LCD Font (Ascii Charaters)
+// Author : Pascal Stang
+// Date : 10/19/2001
+// Revised : 10/19/2001
+// Version : 0.1
+// Target MCU : Atmel AVR
+// Editor Tabs : 4
+//
+//*****************************************************************************
+// Modified for use with LPC1114 by Frank Duignan, 6 Sept 2016
+
+
+#ifndef FONT5X7_H
+#define FONT5X7_H
+#include <stdint.h>
+#define FONT_WIDTH 5
+#define FONT_HEIGHT 7
+// standard ascii 5x7 font
+// defines ascii characters 0x20-0x7F (32-127)
+const uint8_t Font5x7[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00,// (space)
+ 0x00, 0x00, 0x5F, 0x00, 0x00,// !
+ 0x00, 0x07, 0x00, 0x07, 0x00,// "
+ 0x14, 0x7F, 0x14, 0x7F, 0x14,// #
+ 0x24, 0x2A, 0x7F, 0x2A, 0x12,// $
+ 0x23, 0x13, 0x08, 0x64, 0x62,// %
+ 0x36, 0x49, 0x55, 0x22, 0x50,// &
+ 0x00, 0x05, 0x03, 0x00, 0x00,// '
+ 0x00, 0x1C, 0x22, 0x41, 0x00,// (
+ 0x00, 0x41, 0x22, 0x1C, 0x00,// )
+ 0x08, 0x2A, 0x1C, 0x2A, 0x08,// *
+ 0x08, 0x08, 0x3E, 0x08, 0x08,// +
+ 0x00, 0x50, 0x30, 0x00, 0x00,// ,
+ 0x08, 0x08, 0x08, 0x08, 0x08,// -
+ 0x00, 0x60, 0x60, 0x00, 0x00,// .
+ 0x20, 0x10, 0x08, 0x04, 0x02,// /
+ 0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
+ 0x00, 0x42, 0x7F, 0x40, 0x00,// 1
+ 0x42, 0x61, 0x51, 0x49, 0x46,// 2
+ 0x21, 0x41, 0x45, 0x4B, 0x31,// 3
+ 0x18, 0x14, 0x12, 0x7F, 0x10,// 4
+ 0x27, 0x45, 0x45, 0x45, 0x39,// 5
+ 0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
+ 0x01, 0x71, 0x09, 0x05, 0x03,// 7
+ 0x36, 0x49, 0x49, 0x49, 0x36,// 8
+ 0x06, 0x49, 0x49, 0x29, 0x1E,// 9
+ 0x00, 0x36, 0x36, 0x00, 0x00,// :
+ 0x00, 0x56, 0x36, 0x00, 0x00,// ;
+ 0x00, 0x08, 0x14, 0x22, 0x41,// <
+ 0x14, 0x14, 0x14, 0x14, 0x14,// =
+ 0x41, 0x22, 0x14, 0x08, 0x00,// >
+ 0x02, 0x01, 0x51, 0x09, 0x06,// ?
+ 0x32, 0x49, 0x79, 0x41, 0x3E,// @
+ 0x7E, 0x11, 0x11, 0x11, 0x7E,// A
+ 0x7F, 0x49, 0x49, 0x49, 0x36,// B
+ 0x3E, 0x41, 0x41, 0x41, 0x22,// C
+ 0x7F, 0x41, 0x41, 0x22, 0x1C,// D
+ 0x7F, 0x49, 0x49, 0x49, 0x41,// E
+ 0x7F, 0x09, 0x09, 0x01, 0x01,// F
+ 0x3E, 0x41, 0x41, 0x51, 0x32,// G
+ 0x7F, 0x08, 0x08, 0x08, 0x7F,// H
+ 0x00, 0x41, 0x7F, 0x41, 0x00,// I
+ 0x20, 0x40, 0x41, 0x3F, 0x01,// J
+ 0x7F, 0x08, 0x14, 0x22, 0x41,// K
+ 0x7F, 0x40, 0x40, 0x40, 0x40,// L
+ 0x7F, 0x02, 0x04, 0x02, 0x7F,// M
+ 0x7F, 0x04, 0x08, 0x10, 0x7F,// N
+ 0x3E, 0x41, 0x41, 0x41, 0x3E,// O
+ 0x7F, 0x09, 0x09, 0x09, 0x06,// P
+ 0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
+ 0x7F, 0x09, 0x19, 0x29, 0x46,// R
+ 0x46, 0x49, 0x49, 0x49, 0x31,// S
+ 0x01, 0x01, 0x7F, 0x01, 0x01,// T
+ 0x3F, 0x40, 0x40, 0x40, 0x3F,// U
+ 0x1F, 0x20, 0x40, 0x20, 0x1F,// V
+ 0x7F, 0x20, 0x18, 0x20, 0x7F,// W
+ 0x63, 0x14, 0x08, 0x14, 0x63,// X
+ 0x03, 0x04, 0x78, 0x04, 0x03,// Y
+ 0x61, 0x51, 0x49, 0x45, 0x43,// Z
+ 0x00, 0x00, 0x7F, 0x41, 0x41,// [
+ 0x02, 0x04, 0x08, 0x10, 0x20,// "\"
+ 0x41, 0x41, 0x7F, 0x00, 0x00,// ]
+ 0x04, 0x02, 0x01, 0x02, 0x04,// ^
+ 0x40, 0x40, 0x40, 0x40, 0x40,// _
+ 0x00, 0x01, 0x02, 0x04, 0x00,// `
+ 0x20, 0x54, 0x54, 0x54, 0x78,// a
+ 0x7F, 0x48, 0x44, 0x44, 0x38,// b
+ 0x38, 0x44, 0x44, 0x44, 0x20,// c
+ 0x38, 0x44, 0x44, 0x48, 0x7F,// d
+ 0x38, 0x54, 0x54, 0x54, 0x18,// e
+ 0x08, 0x7E, 0x09, 0x01, 0x02,// f
+ 0x08, 0x14, 0x54, 0x54, 0x3C,// g
+ 0x7F, 0x08, 0x04, 0x04, 0x78,// h
+ 0x00, 0x44, 0x7D, 0x40, 0x00,// i
+ 0x20, 0x40, 0x44, 0x3D, 0x00,// j
+ 0x00, 0x7F, 0x10, 0x28, 0x44,// k
+ 0x00, 0x41, 0x7F, 0x40, 0x00,// l
+ 0x7C, 0x04, 0x18, 0x04, 0x78,// m
+ 0x7C, 0x08, 0x04, 0x04, 0x78,// n
+ 0x38, 0x44, 0x44, 0x44, 0x38,// o
+ 0x7C, 0x14, 0x14, 0x14, 0x08,// p
+ 0x08, 0x14, 0x14, 0x18, 0x7C,// q
+ 0x7C, 0x08, 0x04, 0x04, 0x08,// r
+ 0x48, 0x54, 0x54, 0x54, 0x20,// s
+ 0x04, 0x3F, 0x44, 0x40, 0x20,// t
+ 0x3C, 0x40, 0x40, 0x20, 0x7C,// u
+ 0x1C, 0x20, 0x40, 0x20, 0x1C,// v
+ 0x3C, 0x40, 0x30, 0x40, 0x3C,// w
+ 0x44, 0x28, 0x10, 0x28, 0x44,// x
+ 0x0C, 0x50, 0x50, 0x50, 0x3C,// y
+ 0x44, 0x64, 0x54, 0x4C, 0x44,// z
+ 0x00, 0x08, 0x36, 0x41, 0x00,// {
+ 0x00, 0x00, 0x7F, 0x00, 0x00,// |
+ 0x00, 0x41, 0x36, 0x08, 0x00,// }
+ 0x08, 0x08, 0x2A, 0x1C, 0x08,// ->
+ 0x08, 0x1C, 0x2A, 0x08, 0x08 // <-
+};
+
+#endif
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lis3dh.h Wed Jun 24 11:37:11 2020 +0000
@@ -0,0 +1,108 @@
+#include <mbed.h>
+SPI spi(P0_6,P0_4,P0_7); // P0_4 = MISO, P0_6 = MOSI, P0_7 = SCK
+DigitalOut LIS3D_CS(P0_3); // Chip select for the LIS3DH : When low SPI mode is enabled
+DigitalIn int1(P0_1);
+class lis3dh
+{
+public:
+ lis3dh() {};
+ void begin()
+ {
+ LIS3D_CS = 1; // disable SPI mode for a moment
+ spi.format(8,3);
+ spi.frequency(400000);
+
+ LIS3D_CS = 0; //
+ spi.write(0x1e); // Turn off internal pull-ups as we are using SPI to save power
+ spi.write(0x90);
+ LIS3D_CS = 1; //
+
+ LIS3D_CS = 0;
+ spi.write(0x1f); // enable the temperature sensor and the ADC
+ spi.write(0xc0);
+ LIS3D_CS = 1;
+
+ LIS3D_CS = 0;
+ spi.write(0x20); // configure chip for 100Hz, high resolution, normal mode, all axes
+ spi.write(0b01110111);
+ LIS3D_CS = 1;
+
+
+ LIS3D_CS = 0;
+ spi.write(0x23); // Turn on HR mode
+ spi.write(0x88);
+ LIS3D_CS = 1;
+
+
+ LIS3D_CS = 0;
+ spi.write(0x22); // Enable data ready output on INT1 (P0_1)
+ spi.write(0x10);
+ LIS3D_CS = 1;
+
+
+
+
+ }
+
+ int who_am_i()
+ {
+ LIS3D_CS = 0;
+ // Send 0x8f, the command to read the WHOAMI register
+ spi.write(0x8f);
+ // Send a dummy byte to receive the contents of the WHOAMI register
+ int whoami = spi.write(0x00);
+ LIS3D_CS = 1;
+ return whoami; // Should return 55 decimal or 33 Hex
+ }
+
+ int dataReady()
+ {
+ LIS3D_CS = 0;
+ // Send 0xa7, the command to read the status register (0x27)
+ spi.write(0xa7);
+ // Send a dummy byte to receive the contents of the register
+ int status = spi.write(0x00);
+ LIS3D_CS = 1; //
+ /*if (status & 0x08)
+ status = 1;
+ else
+ status = 0;
+ */
+ return int1; // return 1 if data ready
+ }
+ int read(int &X, int &Y, int &Z)
+ {
+ int16_t L,H;
+ int16_t result;
+ LIS3D_CS = 0;
+ // Send 0x8f, the command to read the WHOAMI register
+ spi.write(0xe8);
+ // Send a dummy byte to receive the contents of the register
+ L = spi.write(0x00);
+ // Send a dummy byte to receive the contents of the register
+ H = spi.write(0x00);
+ result = (H << 8) + L;
+ X = result;
+
+ // Send a dummy byte to receive the contents of the register
+ L = spi.write(0x00);
+ // Send a dummy byte to receive the contents of the register
+ H = spi.write(0x00);
+ result = (H << 8) + L;
+ Y = result;
+
+ // Send a dummy byte to receive the contents of the register
+ L = spi.write(0x00);
+ // Send a dummy byte to receive the contents of the register
+ H = spi.write(0x00);
+ result = (H << 8) + L;
+ Z = result;
+
+ LIS3D_CS = 1;
+
+ return 0;
+ }
+
+private:
+
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Wed Jun 24 11:37:11 2020 +0000
@@ -0,0 +1,135 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mbed.h"
+#include "ble/BLE.h"
+#include "LEDService.h"
+#include "accelService.h"
+#include "oled.h"
+#define enable_interrupts() asm(" cpsie i ")
+#define disable_interrupts() asm(" cpsid i ")
+
+
+DigitalOut myled(P0_29);
+
+const static char DEVICE_NAME[] = "CJMCU-8223";
+static const uint16_t uuid16_list[] = {LEDService::LED_SERVICE_UUID,accelService::ACCEL_SERVICE_UUID};
+accelService *AccelServicePtr;
+LEDService *ledServicePtr;
+
+void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
+{
+ BLE::Instance().gap().startAdvertising();
+}
+
+/**
+ * This callback allows the LEDService to receive updates to the ledState Characteristic.
+ *
+ * @param[in] params
+ * Information about the characterisitc being updated.
+ */
+void onDataWrittenCallback(const GattWriteCallbackParams *params) {
+ if ((params->handle == ledServicePtr->getValueHandle()) && (params->len == 1)) {
+ myled = *(params->data);
+ }
+}
+void onDataReadCallback(const GattReadCallbackParams *params) {
+
+}
+/**
+ * This function is called when the ble initialization process has failed
+ */
+void onBleInitError(BLE &ble, ble_error_t error)
+{
+ /* Initialization error handling should go here */
+}
+
+/**
+ * Callback triggered when the ble initialization process has finished
+ */
+void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
+{
+ BLE& ble = params->ble;
+ ble_error_t error = params->error;
+
+ if (error != BLE_ERROR_NONE) {
+ /* In case of error, forward the error handling to onBleInitError */
+ onBleInitError(ble, error);
+ return;
+ }
+
+ /* Ensure that it is the default instance of BLE */
+ if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
+ return;
+ }
+
+ ble.gap().onDisconnection(disconnectionCallback);
+ ble.gattServer().onDataWritten(onDataWrittenCallback);
+ ble.gattServer().onDataRead(onDataReadCallback);
+ bool initialValueForLEDCharacteristic = false;
+ ledServicePtr = new LEDService(ble, initialValueForLEDCharacteristic);
+ int16_t initialValue = 0;
+ AccelServicePtr = new accelService(ble,initialValue);
+
+ /* setup advertising */
+ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
+ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
+ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
+ ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+ ble.gap().setAdvertisingInterval(100); /* 100ms. */
+ ble.gap().startAdvertising();
+}
+oled Oled;
+int main(void)
+{
+
+ int Count=0;
+ Oled.begin();
+ Lis3dh.begin();
+ Oled.print(0,0 ,"Hello");
+
+
+ BLE &ble = BLE::Instance();
+ ble.init(bleInitComplete);
+
+ while (ble.hasInitialized() == false) {
+ Oled.print(0,0,"BLE init fail");
+ myled = 1;
+ wait(0.2);
+ myled = 0;
+ wait(0.1);
+
+ /* spin loop */ }
+ Oled.print(0,0,"BLE init done");
+ while (true) {
+ // update the values for the BLE interface
+ AccelServicePtr->poll();
+ int x,y,z;
+ x = 1;
+ y = 2;
+ z = 3;
+ // show the values on the display
+ if (Lis3dh.dataReady())
+ {
+ Lis3dh.read(x,y,z);
+ Oled.print(0,0,x/16);
+ Oled.print(0,1,y/16);
+ Oled.print(0,2,z/16);
+ }
+ ble.waitForEvent();
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Wed Jun 24 11:37:11 2020 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nRF51822.lib Wed Jun 24 11:37:11 2020 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#c90ae1400bf2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/oled.h Wed Jun 24 11:37:11 2020 +0000
@@ -0,0 +1,179 @@
+// oled.h
+// This class is for the SSD1306 OLED
+//
+#include <mbed.h>
+#include "font5x7.h"
+I2C i2c(P0_30, P0_0); // SDA is on P0_30, SCL is on P0_0
+class oled
+{
+
+public:
+ oled() {};
+ void clear()
+ {
+ for (int i = 0; i < 8; i++)
+ {
+ clearOLEDLine(i);
+ }
+ }
+ void begin()
+ {
+ resetOLED();
+ clear();
+ }
+ void print(int Col, int Row, const char *Text)
+ {
+ // write the supplied text (up to 25 bytes) to the given display line
+ int i;
+ uint8_t RowData[128];
+ for (i = 0; i < 128; i++)
+ RowData[i] = 0;
+ while (*Text) {
+ for (i = 0; i < FONT_WIDTH; i++)
+ {
+ RowData[Col * FONT_WIDTH + i] = Font5x7[FONT_WIDTH * ((*Text) - 32) + i];
+ }
+ Col++;
+ Text++;
+ if (Col > 24)
+ break; // Can't print past end of the screen
+ }
+ writeOLEDLine(Row, RowData);
+ }
+ void print(int Col, int Row, int32_t Value)
+ {
+ char Text[20];
+ int2Text(Text,Value);
+ print(Col,Row,Text);
+ }
+
+private:
+ void writeOLEDLine(int LineNumber, uint8_t *Values)
+ {
+ // Writes the set of values to the given line number
+ writeOLEDRegister(0x00, 0x21);
+ writeOLEDRegister(0x00, 0);
+ writeOLEDRegister(0x00, 127);
+ writeOLEDRegister(0x00, 0x22);
+ writeOLEDRegister(0x00, LineNumber); // Page address
+ writeOLEDRegister(0x00, 7);
+ writeOLEDBytes(0x40, 128, Values);
+ }
+ uint8_t writeOLEDRegister(uint8_t RegNum, uint8_t Value)
+ {
+ char TXData[2];
+ TXData[0] = RegNum;
+ TXData[1] = Value;
+ return i2c.write(0x3c << 1,(const char *)TXData,2);
+ }
+ void resetOLED()
+ {
+ // Reset sequence got from https://github.com/adafruit/Adafruit_SSD1306/blob/master/Adafruit_SSD1306.cpp
+ writeOLEDRegister(0x00, 0xae);
+ writeOLEDRegister(0x00, 0xd5);
+ writeOLEDRegister(0x00, 0x80);
+ writeOLEDRegister(0x00, 0xa8);
+ writeOLEDRegister(0x00, 63);
+ writeOLEDRegister(0x00, 0xd3);
+ writeOLEDRegister(0x00, 0);
+ writeOLEDRegister(0x00, 0x40);
+ writeOLEDRegister(0x00, 0x8d);
+ writeOLEDRegister(0x00, 0x14);
+ writeOLEDRegister(0x00, 0x20);
+ writeOLEDRegister(0x00, 0x00);
+ writeOLEDRegister(0x00, 0xa1);
+ writeOLEDRegister(0x00, 0xc8);
+
+ writeOLEDRegister(0x00, 0xda);
+ writeOLEDRegister(0x00, 0x12);
+ writeOLEDRegister(0x00, 0x81);
+ writeOLEDRegister(0x00, 0xcf);
+
+ writeOLEDRegister(0x00, 0xd9);
+ writeOLEDRegister(0x00, 0xf1);
+ writeOLEDRegister(0x00, 0xdb);
+ writeOLEDRegister(0x00, 0x40);
+ writeOLEDRegister(0x00, 0xa4);
+ writeOLEDRegister(0x00, 0xa6);
+ writeOLEDRegister(0x00, 0x2e);
+ writeOLEDRegister(0x00, 0xaf);
+ }
+ void clearOLEDLine(int LineNumber)
+ {
+ // Clears the given line (range 0 to 7) on the display
+ // A line is 8 pixels high
+ writeOLEDRegister(0x00, 0x21);
+ writeOLEDRegister(0x00, 0);
+ writeOLEDRegister(0x00, 127);
+ writeOLEDRegister(0x00, 0x22);
+ writeOLEDRegister(0x00, LineNumber); // Page address
+ writeOLEDRegister(0x00, 7);
+ fillOLEDBytes(0x40, 128, 0x00);
+ }
+
+
+ uint8_t fillOLEDBytes(uint8_t RegNum, uint8_t Count, uint8_t Value)
+ {
+ // Repeatedly writes the given Value to the OLED memory - useful
+ // for clearing the display
+ uint8_t TXData[Count+1];
+ int i;
+ TXData[0] = RegNum;
+ for (i = 0; i < Count; i++)
+ {
+ TXData[i + 1] = Value;
+ }
+ return i2c.write(0x3c << 1,(const char *)TXData,Count+1);
+ }
+ uint8_t writeOLEDBytes(uint8_t RegNum, uint8_t Count, uint8_t *Values)
+ {
+ // Writes the array of up to 128 bytes to the OLED display
+ if (Count > 128)
+ return -1;
+ uint8_t TXData[Count+1];
+ int i;
+ TXData[0] = RegNum;
+ for (i = 0; i < Count; i++)
+ {
+ TXData[i + 1] = Values[i];
+ }
+ return i2c.write(0x3c << 1,(const char *)TXData,Count+1);
+ }
+
+
+ void int2Text(char *Text, int32_t Value)
+ {
+ int index;
+ Text[11]=0;
+ if (Value < 0)
+ {
+ Text[0]='-';
+ Value = -Value;
+ }
+ else
+ {
+ Text[0] = '+';
+ }
+ for (index = 0; index < 10;index++)
+ {
+ Text[10-index]=(Value % 10) + '0';
+ Value = Value / 10;
+ }
+ }
+ void int2Hex(char *Hex, uint32_t Value)
+ {
+ int temp;
+ int index;
+ Hex[8]=0;
+ for (index = 0; index < 8;index++)
+ {
+ temp = Value % 16;
+ if (temp < 10)
+ temp = temp + '0';
+ else
+ temp = temp + 'A' - 10;
+ Hex[7-index]=temp;
+ Value = Value / 16;
+ }
+ }
+};