Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed Adafruit_GFX
Revision 0:c4c874d702f9, committed 2019-06-15
- Comitter:
- 21400688
- Date:
- Sat Jun 15 20:39:39 2019 +0000
- Commit message:
- first commit
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adafruit_GFX.lib Sat Jun 15 20:39:39 2019 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/nkhorman/code/Adafruit_GFX/#7fb1d4d3525d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/PixelArray/PixelArray.cpp Sat Jun 15 20:39:39 2019 +0000
@@ -0,0 +1,127 @@
+#include "PixelArray.h"
+
+PixelArray::PixelArray(int size)
+{
+ pbufsize = size;
+ pbuf = new int[pbufsize];
+ SetAll(0x0); // initialise memory to zeros
+
+}
+
+PixelArray::~PixelArray()
+{
+ delete[] pbuf;
+}
+
+void PixelArray::SetAll(unsigned int value)
+{
+ // for each pixel
+ for (int i=0 ; i < pbufsize; i++) {
+ __set_pixel(i,value);
+ }
+}
+
+
+void PixelArray::SetAllI(unsigned char value)
+{
+ // for each pixel
+ for (int i=0 ; i < pbufsize; i++) {
+ __set_pixel_component(i,3,value);
+ }
+}
+
+
+
+void PixelArray::SetAllR(unsigned char value)
+{
+ // for each pixel
+ for (int i=0 ; i < pbufsize; i++) {
+ __set_pixel_component(i,2,value);
+ }
+}
+
+void PixelArray::SetAllG(unsigned char value)
+{
+ // for each pixel
+ for (int i=0 ; i < pbufsize; i++) {
+ __set_pixel_component(i,1,value);
+ }
+}
+
+void PixelArray::SetAllB(unsigned char value)
+{
+ // for each pixel
+ for (int i=0 ; i < pbufsize; i++) {
+ __set_pixel_component(i,0,value);
+ }
+}
+
+
+
+
+
+void PixelArray::Set(int i, unsigned int value)
+{
+ if ((i >= 0) && (i < pbufsize)) {
+ __set_pixel(i,value);
+ }
+}
+
+
+
+void PixelArray::SetI(int i, unsigned char value)
+{
+ if ((i >= 0) && (i < pbufsize)) {
+ __set_pixel_component(i,3,value);
+ }
+}
+
+
+void PixelArray::SetR(int i, unsigned char value)
+{
+ if ((i >= 0) && (i < pbufsize)) {
+ __set_pixel_component(i,2,value);
+ }
+}
+
+void PixelArray::SetG(int i, unsigned char value)
+{
+ if ((i >= 0) && (i < pbufsize)) {
+ __set_pixel_component(i,1,value);
+ }
+}
+
+void PixelArray::SetB(int i, unsigned char value)
+{
+ if ((i >= 0) && (i < pbufsize)) {
+ __set_pixel_component(i,0,value);
+ }
+}
+
+
+int* PixelArray::getBuf()
+{
+ return (pbuf);
+}
+
+
+// set either the I,R,G,B value of specific pixel channel
+void PixelArray::__set_pixel_component(int index, int channel, int value)
+{
+
+ // AND with 0x00 shifted to the right location to clear the bits
+ pbuf[index] &= ~(0xFF << (8 * channel));
+
+ // Set the bits with an OR
+ pbuf[index] |= (value << (8 * channel));
+}
+
+
+// set either the I,R,G,B value of specific pixel channel
+void PixelArray::__set_pixel(int index, int value)
+{
+ // AND with 0x00 shifted to the right location to clear the bits
+ pbuf[index] = value;
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/PixelArray/PixelArray.h Sat Jun 15 20:39:39 2019 +0000
@@ -0,0 +1,68 @@
+/* Copyright (c) 2012 cstyles, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef PixelArray_H
+#define PixelArray_H
+
+#include "mbed.h"
+
+//!Library for the WS2812 RGB LED with integrated controller
+/*!
+PixelArray
+*/
+class PixelArray
+{
+public:
+ //!Creates an instance of the class.
+ /*!
+ Pixel Array
+ */
+ PixelArray(int);
+
+ /*!
+ Destroys instance.
+ */
+ ~PixelArray();
+
+ int* getBuf();
+
+ void SetAll(unsigned int);
+ void SetAllI(unsigned char);
+ void SetAllR(unsigned char);
+ void SetAllG(unsigned char);
+ void SetAllB(unsigned char);
+
+ // location, value
+ void Set(int, unsigned int);
+ void SetI(int, unsigned char);
+ void SetR(int, unsigned char);
+ void SetG(int, unsigned char);
+ void SetB(int, unsigned char);
+
+private:
+
+ int *pbuf;
+ int pbufsize;
+
+ void __set_pixel_component(int index, int channel, int value);
+ void __set_pixel(int index, int value);
+
+};
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/RemoteIR/ReceiverIR.cpp Sat Jun 15 20:39:39 2019 +0000
@@ -0,0 +1,330 @@
+/**
+ * IR receiver (Version 0.0.4)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+
+#include "ReceiverIR.h"
+
+#define LOCK()
+#define UNLOCK()
+
+#define InRange(x,y) ((((y) * 0.7) < (x)) && ((x) < ((y) * 1.3)))
+
+/**
+ * Constructor.
+ *
+ * @param rxpin Pin for receive IR signal.
+ */
+ReceiverIR::ReceiverIR(PinName rxpin) : evt(rxpin) {
+ init_state();
+ evt.fall(this, &ReceiverIR::isr_fall);
+ evt.rise(this, &ReceiverIR::isr_rise);
+ evt.mode(PullUp);
+ ticker.attach_us(this, &ReceiverIR::isr_wdt, 10 * 1000);
+}
+
+/**
+ * Destructor.
+ */
+ReceiverIR::~ReceiverIR() {
+}
+
+/**
+ * Get state.
+ *
+ * @return Current state.
+ */
+ReceiverIR::State ReceiverIR::getState() {
+ LOCK();
+ State s = work.state;
+ UNLOCK();
+ return s;
+}
+
+/**
+ * Get data.
+ *
+ * @param format Pointer to format.
+ * @param buf Buffer of a data.
+ * @param bitlength Bit length of the buffer.
+ *
+ * @return Data bit length.
+ */
+int ReceiverIR::getData(RemoteIR::Format *format, uint8_t *buf, int bitlength) {
+ LOCK();
+
+ if (bitlength < data.bitcount) {
+ UNLOCK();
+ return -1;
+ }
+
+ const int nbits = data.bitcount;
+ const int nbytes = data.bitcount / 8 + (((data.bitcount % 8) != 0) ? 1 : 0);
+ *format = data.format;
+ for (int i = 0; i < nbytes; i++) {
+ buf[i] = data.buffer[i];
+ }
+
+ init_state();
+
+ UNLOCK();
+ return nbits;
+}
+
+void ReceiverIR::init_state(void) {
+ work.c1 = -1;
+ work.c2 = -1;
+ work.c3 = -1;
+ work.d1 = -1;
+ work.d2 = -1;
+ work.state = Idle;
+ data.format = RemoteIR::UNKNOWN;
+ data.bitcount = 0;
+ timer.stop();
+ timer.reset();
+ for (int i = 0; i < sizeof(data.buffer); i++) {
+ data.buffer[i] = 0;
+ }
+}
+
+void ReceiverIR::isr_wdt(void) {
+ LOCK();
+ static int cnt = 0;
+ if ((Idle != work.state) || ((0 <= work.c1) || (0 <= work.c2) || (0 <= work.c3) || (0 <= work.d1) || (0 <= work.d2))) {
+ cnt++;
+ if (cnt > 50) {
+#if 0
+ printf("# WDT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n",
+ work.c1,
+ work.c2,
+ work.c3,
+ work.d1,
+ work.d2,
+ work.state,
+ data.format,
+ data.bitcount);
+#endif
+ init_state();
+ cnt = 0;
+ }
+ } else {
+ cnt = 0;
+ }
+ UNLOCK();
+}
+
+void ReceiverIR::isr_fall(void) {
+ LOCK();
+ switch (work.state) {
+ case Idle:
+ if (work.c1 < 0) {
+ timer.start();
+ work.c1 = timer.read_us();
+ } else {
+ work.c3 = timer.read_us();
+ int a = work.c2 - work.c1;
+ int b = work.c3 - work.c2;
+ if (InRange(a, RemoteIR::TUS_NEC * 16) && InRange(b, RemoteIR::TUS_NEC * 8)) {
+ /*
+ * NEC.
+ */
+ data.format = RemoteIR::NEC;
+ work.state = Receiving;
+ data.bitcount = 0;
+ } else if (InRange(a, RemoteIR::TUS_NEC * 16) && InRange(b, RemoteIR::TUS_NEC * 4)) {
+ /*
+ * NEC Repeat.
+ */
+ data.format = RemoteIR::NEC_REPEAT;
+ work.state = Received;
+ data.bitcount = 0;
+ work.c1 = -1;
+ work.c2 = -1;
+ work.c3 = -1;
+ work.d1 = -1;
+ work.d2 = -1;
+ } else if (InRange(a, RemoteIR::TUS_AEHA * 8) && InRange(b, RemoteIR::TUS_AEHA * 4)) {
+ /*
+ * AEHA.
+ */
+ data.format = RemoteIR::AEHA;
+ work.state = Receiving;
+ data.bitcount = 0;
+ } else if (InRange(a, RemoteIR::TUS_AEHA * 8) && InRange(b, RemoteIR::TUS_AEHA * 8)) {
+ /*
+ * AEHA Repeat.
+ */
+ data.format = RemoteIR::AEHA_REPEAT;
+ work.state = Received;
+ data.bitcount = 0;
+ work.c1 = -1;
+ work.c2 = -1;
+ work.c3 = -1;
+ work.d1 = -1;
+ work.d2 = -1;
+ } else {
+ init_state();
+ }
+ }
+ break;
+ case Receiving:
+ if (RemoteIR::NEC == data.format) {
+ work.d2 = timer.read_us();
+ int a = work.d2 - work.d1;
+ if (InRange(a, RemoteIR::TUS_NEC * 3)) {
+ data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8));
+ } else if (InRange(a, RemoteIR::TUS_NEC * 1)) {
+ data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8));
+ }
+ data.bitcount++;
+#if 0
+ /*
+ * Length of NEC is always 32 bits.
+ */
+ if (32 <= data.bitcount) {
+ data.state = Received;
+ work.c1 = -1;
+ work.c2 = -1;
+ work.c3 = -1;
+ work.d1 = -1;
+ work.d2 = -1;
+ }
+#else
+ /*
+ * Set timeout for tail detection automatically.
+ */
+ timeout.detach();
+ timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_NEC * 5);
+#endif
+ } else if (RemoteIR::AEHA == data.format) {
+ work.d2 = timer.read_us();
+ int a = work.d2 - work.d1;
+ if (InRange(a, RemoteIR::TUS_AEHA * 3)) {
+ data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8));
+ } else if (InRange(a, RemoteIR::TUS_AEHA * 1)) {
+ data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8));
+ }
+ data.bitcount++;
+#if 0
+ /*
+ * Typical length of AEHA is 48 bits.
+ * Please check a specification of your remote controller if you find a problem.
+ */
+ if (48 <= data.bitcount) {
+ data.state = Received;
+ work.c1 = -1;
+ work.c2 = -1;
+ work.c3 = -1;
+ work.d1 = -1;
+ work.d2 = -1;
+ }
+#else
+ /*
+ * Set timeout for tail detection automatically.
+ */
+ timeout.detach();
+ timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_AEHA * 5);
+#endif
+ } else if (RemoteIR::SONY == data.format) {
+ work.d1 = timer.read_us();
+ }
+ break;
+ case Received:
+ break;
+ default:
+ break;
+ }
+ UNLOCK();
+}
+
+void ReceiverIR::isr_rise(void) {
+ LOCK();
+ switch (work.state) {
+ case Idle:
+ if (0 <= work.c1) {
+ work.c2 = timer.read_us();
+ int a = work.c2 - work.c1;
+ if (InRange(a, RemoteIR::TUS_SONY * 4)) {
+ data.format = RemoteIR::SONY;
+ work.state = Receiving;
+ data.bitcount = 0;
+ } else {
+ static const int MINIMUM_LEADER_WIDTH = 150;
+ if (a < MINIMUM_LEADER_WIDTH) {
+ init_state();
+ }
+ }
+ } else {
+ init_state();
+ }
+ break;
+ case Receiving:
+ if (RemoteIR::NEC == data.format) {
+ work.d1 = timer.read_us();
+ } else if (RemoteIR::AEHA == data.format) {
+ work.d1 = timer.read_us();
+ } else if (RemoteIR::SONY == data.format) {
+ work.d2 = timer.read_us();
+ int a = work.d2 - work.d1;
+ if (InRange(a, RemoteIR::TUS_SONY * 2)) {
+ data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8));
+ } else if (InRange(a, RemoteIR::TUS_SONY * 1)) {
+ data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8));
+ }
+ data.bitcount++;
+#if 0
+ /*
+ * How do I know the correct length? (6bits, 12bits, 15bits, 20bits...)
+ * By a model only?
+ * Please check a specification of your remote controller if you find a problem.
+ */
+ if (12 <= data.bitcount) {
+ data.state = Received;
+ work.c1 = -1;
+ work.c2 = -1;
+ work.c3 = -1;
+ work.d1 = -1;
+ work.d2 = -1;
+ }
+#else
+ /*
+ * Set timeout for tail detection automatically.
+ */
+ timeout.detach();
+ timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_SONY * 4);
+#endif
+ }
+ break;
+ case Received:
+ break;
+ default:
+ break;
+ }
+ UNLOCK();
+}
+
+void ReceiverIR::isr_timeout(void) {
+ LOCK();
+#if 0
+ printf("# TIMEOUT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n",
+ work.c1,
+ work.c2,
+ work.c3,
+ work.d1,
+ work.d2,
+ work.state,
+ data.format,
+ data.bitcount);
+#endif
+ if (work.state == Receiving) {
+ work.state = Received;
+ work.c1 = -1;
+ work.c2 = -1;
+ work.c3 = -1;
+ work.d1 = -1;
+ work.d2 = -1;
+ }
+ UNLOCK();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/RemoteIR/ReceiverIR.h Sat Jun 15 20:39:39 2019 +0000
@@ -0,0 +1,98 @@
+/**
+ * IR receiver (Version 0.0.4)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+
+#ifndef _RECEIVER_IR_H_
+#define _RECEIVER_IR_H_
+
+#include <mbed.h>
+
+#include "RemoteIR.h"
+
+/**
+ * IR receiver class.
+ */
+class ReceiverIR {
+public:
+
+ /**
+ * Constructor.
+ *
+ * @param rxpin Pin for receive IR signal.
+ */
+ explicit ReceiverIR(PinName rxpin);
+
+ /**
+ * Destructor.
+ */
+ ~ReceiverIR();
+
+ /**
+ * State.
+ */
+ typedef enum {
+ Idle,
+ Receiving,
+ Received
+ } State;
+
+ /**
+ * Get state.
+ *
+ * @return Current state.
+ */
+ State getState();
+
+ /**
+ * Get data.
+ *
+ * @param format Pointer to format.
+ * @param buf Buffer of a data.
+ * @param bitlength Bit length of the buffer.
+ *
+ * @return Data bit length.
+ */
+ int getData(RemoteIR::Format *format, uint8_t *buf, int bitlength);
+
+private:
+
+ typedef struct {
+ RemoteIR::Format format;
+ int bitcount;
+ uint8_t buffer[64];
+ } data_t;
+
+ typedef struct {
+ State state;
+ int c1;
+ int c2;
+ int c3;
+ int d1;
+ int d2;
+ } work_t;
+
+ InterruptIn evt; /**< Interrupt based input for input. */
+ Timer timer; /**< Timer for WDT. */
+ Ticker ticker; /**< Tciker for tick. */
+ Timeout timeout; /**< Timeout for tail. */
+
+ data_t data;
+ work_t work;
+
+ void init_state(void);
+
+ void isr_wdt(void);
+ void isr_fall(void);
+ void isr_rise(void);
+
+ /**
+ * ISR timeout for tail detection.
+ */
+ void isr_timeout(void);
+
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/RemoteIR/RemoteIR.h Sat Jun 15 20:39:39 2019 +0000
@@ -0,0 +1,31 @@
+/**
+ * IR remote common class (Version 0.0.4)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+
+#ifndef _REMOTE_IR_H_
+#define _REMOTE_IR_H_
+
+class RemoteIR {
+public:
+
+ typedef enum {
+ UNKNOWN,
+ NEC,
+ NEC_REPEAT,
+ AEHA,
+ AEHA_REPEAT,
+ SONY
+ } Format;
+
+ static const int TUS_NEC = 562;
+ static const int TUS_AEHA = 425;
+ static const int TUS_SONY = 600;
+
+private:
+ RemoteIR();
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/RemoteIR/TransmitterIR.cpp Sat Jun 15 20:39:39 2019 +0000
@@ -0,0 +1,300 @@
+/**
+ * IR transmitter (Version 0.0.4)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+
+#include "TransmitterIR.h"
+
+#define LOCK()
+#define UNLOCK()
+
+/**
+ * Constructor.
+ *
+ * @param txpin Pin for transmit IR signal.
+ */
+TransmitterIR::TransmitterIR(PinName txpin) : tx(txpin) {
+ tx.write(0.0);
+ tx.period_us(26.3);
+
+ work.state = Idle;
+ work.bitcount = 0;
+ work.leader = 0;
+ work.data = 0;
+ work.trailer = 0;
+
+ data.format = RemoteIR::UNKNOWN;
+ data.bitlength = 0;
+}
+
+/**
+ * Destructor.
+ */
+TransmitterIR::~TransmitterIR() {
+}
+
+/**
+ * Get state.
+ *
+ * @return Current state.
+ */
+TransmitterIR::State TransmitterIR::getState(void) {
+ LOCK();
+ State s = work.state;
+ UNLOCK();
+ return s;
+}
+
+/**
+ * Set data.
+ *
+ * @param format Format.
+ * @param buf Buffer of a data.
+ * @param bitlength Bit length of the data.
+ *
+ * @return Data bit length.
+ */
+int TransmitterIR::setData(RemoteIR::Format format, uint8_t *buf, int bitlength) {
+ LOCK();
+ if (work.state != Idle) {
+ UNLOCK();
+ return -1;
+ }
+
+ work.state = Leader;
+ work.bitcount = 0;
+ work.leader = 0;
+ work.data = 0;
+ work.trailer = 0;
+
+ data.format = format;
+ data.bitlength = bitlength;
+ const int n = bitlength / 8 + (((bitlength % 8) != 0) ? 1 : 0);
+ for (int i = 0; i < n; i++) {
+ data.buffer[i] = buf[i];
+ }
+
+ switch (format) {
+ case RemoteIR::NEC:
+ ticker.detach();
+ ticker.attach_us(this, &TransmitterIR::tick, RemoteIR::TUS_NEC);
+ break;
+ case RemoteIR::AEHA:
+ ticker.detach();
+ ticker.attach_us(this, &TransmitterIR::tick, RemoteIR::TUS_AEHA);
+ break;
+ case RemoteIR::SONY:
+ ticker.detach();
+ ticker.attach_us(this, &TransmitterIR::tick, RemoteIR::TUS_SONY);
+ break;
+ }
+
+ UNLOCK();
+ return bitlength;
+}
+
+void TransmitterIR::tick(void) {
+ LOCK();
+ switch (work.state) {
+ case Idle:
+ work.bitcount = 0;
+ work.leader = 0;
+ work.data = 0;
+ work.trailer = 0;
+ break;
+ case Leader:
+ if (data.format == RemoteIR::NEC) {
+ /*
+ * NEC.
+ */
+ static const int LEADER_NEC_HEAD = 16;
+ static const int LEADER_NEC_TAIL = 8;
+ if (work.leader < LEADER_NEC_HEAD) {
+ tx.write(0.5);
+ } else {
+ tx.write(0.0);
+ }
+ work.leader++;
+ if ((LEADER_NEC_HEAD + LEADER_NEC_TAIL) <= work.leader) {
+ work.state = Data;
+ }
+ } else if (data.format == RemoteIR::AEHA) {
+ /*
+ * AEHA.
+ */
+ static const int LEADER_AEHA_HEAD = 8;
+ static const int LEADER_AEHA_TAIL = 4;
+ if (work.leader < LEADER_AEHA_HEAD) {
+ tx.write(0.5);
+ } else {
+ tx.write(0.0);
+ }
+ work.leader++;
+ if ((LEADER_AEHA_HEAD + LEADER_AEHA_TAIL) <= work.leader) {
+ work.state = Data;
+ }
+ } else if (data.format == RemoteIR::SONY) {
+ /*
+ * SONY.
+ */
+ static const int LEADER_SONY_HEAD = 4;
+ static const int LEADER_SONY_TAIL = 0;
+ if (work.leader < LEADER_SONY_HEAD) {
+ tx.write(0.5);
+ } else {
+ tx.write(0.0);
+ }
+ work.leader++;
+ if ((LEADER_SONY_HEAD + LEADER_SONY_TAIL) <= work.leader) {
+ work.state = Data;
+ }
+ } else {
+ }
+ break;
+ case Data:
+ if (data.format == RemoteIR::NEC) {
+ /*
+ * NEC.
+ */
+ if (work.data == 0) {
+ tx.write(0.5);
+ work.data++;
+ } else {
+ tx.write(0.0);
+ if (0 != (data.buffer[work.bitcount / 8] & (1 << work.bitcount % 8))) {
+ if (3 <= work.data) {
+ work.bitcount++;
+ work.data = 0;
+ } else {
+ work.data++;
+ }
+ } else {
+ if (1 <= work.data) {
+ work.bitcount++;
+ work.data = 0;
+ } else {
+ work.data++;
+ }
+ }
+ }
+ if (data.bitlength <= work.bitcount) {
+ work.state = Trailer;
+ }
+ } else if (data.format == RemoteIR::AEHA) {
+ /*
+ * AEHA.
+ */
+ if (work.data == 0) {
+ tx.write(0.5);
+ work.data++;
+ } else {
+ tx.write(0.0);
+ if (0 != (data.buffer[work.bitcount / 8] & (1 << work.bitcount % 8))) {
+ if (3 <= work.data) {
+ work.bitcount++;
+ work.data = 0;
+ } else {
+ work.data++;
+ }
+ } else {
+ if (1 <= work.data) {
+ work.bitcount++;
+ work.data = 0;
+ } else {
+ work.data++;
+ }
+ }
+ }
+ if (data.bitlength <= work.bitcount) {
+ work.state = Trailer;
+ }
+ } else if (data.format == RemoteIR::SONY) {
+ /*
+ * SONY.
+ */
+ if (work.data == 0) {
+ tx.write(0.0);
+ work.data++;
+ } else {
+ tx.write(0.5);
+ if (0 != (data.buffer[work.bitcount / 8] & (1 << work.bitcount % 8))) {
+ if (2 <= work.data) {
+ work.bitcount++;
+ work.data = 0;
+ } else {
+ work.data++;
+ }
+ } else {
+ if (1 <= work.data) {
+ work.bitcount++;
+ work.data = 0;
+ } else {
+ work.data++;
+ }
+ }
+ }
+ if (data.bitlength <= work.bitcount) {
+ work.state = Trailer;
+ }
+ } else {
+ }
+ break;
+ case Trailer:
+ if (data.format == RemoteIR::NEC) {
+ /*
+ * NEC.
+ */
+ static const int TRAILER_NEC_HEAD = 1;
+ static const int TRAILER_NEC_TAIL = 2;
+ if (work.trailer < TRAILER_NEC_HEAD) {
+ tx.write(0.5);
+ } else {
+ tx.write(0.0);
+ }
+ work.trailer++;
+ if ((TRAILER_NEC_HEAD + TRAILER_NEC_TAIL) <= work.trailer) {
+ work.state = Idle;
+ //ticker.detach();
+ }
+ } else if (data.format == RemoteIR::AEHA) {
+ /*
+ * AEHA.
+ */
+ static const int TRAILER_AEHA_HEAD = 1;
+ static const int TRAILER_AEHA_TAIL = 8000 / RemoteIR::TUS_AEHA;
+ if (work.trailer < TRAILER_AEHA_HEAD) {
+ tx.write(0.5);
+ } else {
+ tx.write(0.0);
+ }
+ work.trailer++;
+ if ((TRAILER_AEHA_HEAD + TRAILER_AEHA_TAIL) <= work.trailer) {
+ work.state = Idle;
+ //ticker.detach();
+ }
+ } else if (data.format == RemoteIR::SONY) {
+ /*
+ * SONY.
+ */
+ static const int TRAILER_SONY_HEAD = 0;
+ static const int TRAILER_SONY_TAIL = 0;
+ if (work.trailer < TRAILER_SONY_HEAD) {
+ tx.write(0.5);
+ } else {
+ tx.write(0.0);
+ }
+ work.trailer++;
+ if ((TRAILER_SONY_HEAD + TRAILER_SONY_TAIL) <= work.trailer) {
+ work.state = Idle;
+ //ticker.detach();
+ }
+ } else {
+ }
+ break;
+ default:
+ break;
+ }
+ UNLOCK();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/RemoteIR/TransmitterIR.h Sat Jun 15 20:39:39 2019 +0000
@@ -0,0 +1,83 @@
+/**
+ * IR transmitter (Version 0.0.4)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+
+#ifndef _TRANSMITTER_IR_H_
+#define _TRANSMITTER_IR_H_
+
+#include <mbed.h>
+
+#include "RemoteIR.h"
+
+/**
+ * IR transmitter class.
+ */
+class TransmitterIR {
+public:
+
+ /**
+ * Constructor.
+ *
+ * @param txpin Pin for transmit IR signal.
+ */
+ explicit TransmitterIR(PinName txpin);
+
+ /**
+ * Destructor.
+ */
+ ~TransmitterIR();
+
+ typedef enum {
+ Idle,
+ Leader,
+ Data,
+ Trailer
+ } State;
+
+ /**
+ * Get state.
+ *
+ * @return Current state.
+ */
+ State getState(void);
+
+ /**
+ * Set data.
+ *
+ * @param format Format.
+ * @param buf Buffer of a data.
+ * @param bitlength Bit length of the data.
+ *
+ * @return Data bit length.
+ */
+ int setData(RemoteIR::Format format, uint8_t *buf, int bitlength);
+
+private:
+
+ typedef struct {
+ State state;
+ int bitcount;
+ int leader;
+ int data;
+ int trailer;
+ } work_t;
+
+ typedef struct {
+ RemoteIR::Format format;
+ int bitlength;
+ uint8_t buffer[64];
+ } data_t;
+
+ PwmOut tx;
+ Ticker ticker;
+ data_t data;
+ work_t work;
+
+ void tick();
+
+};
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TB6612FNG/TB6612FNG.cpp Sat Jun 15 20:39:39 2019 +0000
@@ -0,0 +1,111 @@
+/* File: TB6612FNG.h
+ * Author: Robert Abad Copyright (c) 2013
+ *
+ * Desc: driver for TB6612FNG Motor Driver. For further details see
+ * header file, TB6612FNG.h
+ */
+
+#include "mbed.h"
+#include "TB6612FNG.h"
+
+#define SIGNAL_HIGH (1)
+#define SIGNAL_LOW (0)
+
+TB6612FNG::TB6612FNG( PinName pinPwmA, PinName pinAin1, PinName pinAin2,
+ PinName pinPwmB, PinName pinBin1, PinName pinBin2,
+ PinName pinNStby ) :
+pwmA(pinPwmA),
+Ain1(pinAin1),
+Ain2(pinAin2),
+pwmB(pinPwmB),
+Bin1(pinBin1),
+Bin2(pinBin2),
+nStby(pinNStby)
+{
+ Ain1 = SIGNAL_LOW;
+ Ain2 = SIGNAL_LOW;
+ Bin1 = SIGNAL_LOW;
+ Bin2 = SIGNAL_LOW;
+ pwmA.period(TB6612FNG_PWM_PERIOD_DEFAULT);
+ pwmA = TB6612FNG_PWM_PULSEWIDTH_DEFAULT;
+ pwmB.period(TB6612FNG_PWM_PERIOD_DEFAULT);
+ pwmB = TB6612FNG_PWM_PULSEWIDTH_DEFAULT;
+ nStby = SIGNAL_LOW;
+}
+
+void TB6612FNG::setPwmA(float fPeriod, float fPulsewidth)
+{
+ pwmA.period(fPeriod);
+ pwmA = fPulsewidth;
+}
+
+void TB6612FNG::setPwmAperiod(float fPeriod)
+{
+ pwmA.period(fPeriod);
+}
+
+void TB6612FNG::setPwmApulsewidth(float fPulsewidth)
+{
+ pwmA = fPulsewidth;
+}
+
+void TB6612FNG::setPwmB(float fPeriod, float fPulsewidth)
+{
+ pwmB.period(fPeriod);
+ pwmB = fPulsewidth;
+}
+
+void TB6612FNG::setPwmBperiod(float fPeriod)
+{
+ pwmB.period(fPeriod);
+}
+
+void TB6612FNG::setPwmBpulsewidth(float fPulsewidth)
+{
+ pwmB = fPulsewidth;
+}
+
+void TB6612FNG::standby(void)
+{
+ nStby = SIGNAL_LOW;
+}
+
+void TB6612FNG::motorA_stop(void)
+{
+ Ain1 = SIGNAL_LOW;
+ Ain2 = SIGNAL_LOW;
+}
+
+void TB6612FNG::motorA_ccw(void)
+{
+ Ain1 = SIGNAL_LOW;
+ Ain2 = SIGNAL_HIGH;
+ nStby = SIGNAL_HIGH;
+}
+
+void TB6612FNG::motorA_cw(void)
+{
+ Ain1 = SIGNAL_HIGH;
+ Ain2 = SIGNAL_LOW;
+ nStby = SIGNAL_HIGH;
+}
+
+void TB6612FNG::motorB_stop(void)
+{
+ Bin1 = SIGNAL_LOW;
+ Bin2 = SIGNAL_LOW;
+}
+
+void TB6612FNG::motorB_ccw(void)
+{
+ Bin1 = SIGNAL_LOW;
+ Bin2 = SIGNAL_HIGH;
+ nStby = SIGNAL_HIGH;
+}
+
+void TB6612FNG::motorB_cw(void)
+{
+ Bin1 = SIGNAL_HIGH;
+ Bin2 = SIGNAL_LOW;
+ nStby = SIGNAL_HIGH;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TB6612FNG/TB6612FNG.h Sat Jun 15 20:39:39 2019 +0000
@@ -0,0 +1,96 @@
+/* File: TB6612FNG.h
+ * Author: Robert Abad Copyright (c) 2013
+ *
+ * Desc: driver for Toshiiba TB6612FNG Motor Driver. Though this motor driver
+ * can be used to drive two motors (A and B), it can be used to drive
+ * just one. Member functions can be used to set period and pulsewidth
+ * but are not necessary as the constructor does set default values).
+ * The datasheet for this device can be found here:
+ * http://www.toshiba.com/taec/components2/Datasheet_Sync/261/27197.pdf
+ *
+ * Below is some sample code:
+ *
+ * #include "mbed.h"
+ * #include "TB6612FNG.h"
+ *
+ * #define TB6612FNG_PIN_PWMA (p22)
+ * #define TB6612FNG_PIN_AIN1 (p17)
+ * #define TB6612FNG_PIN_AIN2 (p16)
+ * #define TB6612FNG_PIN_PWMB (p21)
+ * #define TB6612FNG_PIN_BIN1 (p19)
+ * #define TB6612FNG_PIN_BIN2 (p20)
+ * #define TB6612FNG_PIN_NSTBY (p18)
+ * TB6612FNG motorDriver( TB6612FNG_PIN_PWMA, TB6612FNG_PIN_AIN1, TB6612FNG_PIN_AIN2,
+ * TB6612FNG_PIN_PWMB, TB6612FNG_PIN_BIN1, TB6612FNG_PIN_BIN2,
+ * TB6612FNG_PIN_NSTBY );
+ * float fPwmPeriod;
+ * float fPwmPulsewidth;
+ *
+ * int main()
+ * {
+ * fPwmPeriod = 0.00002f; // 50KHz
+ * fPwmPulsewidth = 0.50; // 50% duty cycle
+ * motorDriver.setPwmAperiod(fPwmPeriod);
+ * motorDriver.setPwmBperiod(fPwmPeriod);
+ * motorDriver.setPwmApulsewidth(fPwmPulsewidth);
+ * motorDriver.setPwmBpulsewidth(fPwmPulsewidth);
+ *
+ * while(1)
+ * {
+ * motorDriver.motorA_ccw();
+ * wait(2);
+ * motorDriver.motorA_cw();
+ * wait(2);
+ * motorDriver.motorA_stop();
+ * wait(2);
+ * motorDriver.motorB_ccw();
+ * wait(2);
+ * motorDriver.motorB_cw();
+ * wait(2);
+ * motorDriver.motorB_stop();
+ * wait(2);
+ * }
+ * }
+ */
+
+#ifndef __TB6612FNG_H__
+#define __TB6612FNG_H__
+
+#include "mbed.h"
+
+#define TB6612FNG_PWM_PERIOD_DEFAULT (0.00002) // 50KHz
+#define TB6612FNG_PWM_PULSEWIDTH_DEFAULT (0.50) // 속도 이거다!
+
+class TB6612FNG
+{
+public:
+ TB6612FNG( PinName pinPwmA, PinName pinAin1, PinName pinAin2,
+ PinName pinPwmB, PinName pinBin1, PinName pinBin2,
+ PinName pinNStby );
+ void setPwmA(float fPeriod, float fPulsewidth);
+ void setPwmAperiod(float fPeriod);
+ void setPwmApulsewidth(float fPulsewidth);
+ void setPwmB(float fPeriod, float fPulsewidth);
+ void setPwmBperiod(float fPeriod);
+ void setPwmBpulsewidth(float fPulsewidth);
+ void standby(void);
+ void motorA_stop(void);
+ void motorA_ccw(void);
+ void motorA_cw(void);
+ void motorB_stop(void);
+ void motorB_ccw(void);
+ void motorB_cw(void);
+ void upPulsewidth(void);
+ void downPulsewidth(void);
+
+private:
+ PwmOut pwmA;
+ DigitalOut Ain1;
+ DigitalOut Ain2;
+ PwmOut pwmB;
+ DigitalOut Bin1;
+ DigitalOut Bin2;
+ DigitalOut nStby;
+};
+
+#endif /* __TB6612FNG_H__ */
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Ultrasonic.cpp Sat Jun 15 20:39:39 2019 +0000
@@ -0,0 +1,70 @@
+#include "Ultrasonic.h"
+
+Ultrasonic::Ultrasonic(PinName trigPin, PinName echoPin, float tick, bool repeat)
+ : _trig(trigPin), _echo(echoPin), _toVal(tick), _repeat(repeat)
+{
+ _done = 0;
+ _timer.reset();
+ _echo.rise(this, &Ultrasonic::_startT);
+ _echo.fall(this, &Ultrasonic::_endT);
+ if (_repeat) _ticker.attach(this, &Ultrasonic::_ticker_cb, _toVal);
+}
+
+Ultrasonic::~Ultrasonic() {}
+
+void Ultrasonic::_startT(void)
+{
+ _timer.start();
+}
+void Ultrasonic::_endT(void)
+{
+ _timer.stop();
+ _pulseDuration = _timer.read_us();
+ _distance = _pulseDuration / 58;
+ _timer.reset();
+ _done = 1;
+}
+
+
+void Ultrasonic::trig()
+{
+ _echo.enable_irq();
+ wait_us(2);
+ _trig = 1;
+ wait_us(10);
+ _trig = 0;
+}
+void Ultrasonic::_ticker_cb(void)
+{
+ this->trig();
+}
+
+int Ultrasonic::getDistance(void)
+{
+ return _distance;
+}
+int Ultrasonic::getPulseDuration(void)
+{
+ return _pulseDuration;
+}
+
+void Ultrasonic::pauseMeasure(void)
+{
+ _repeat = false;
+ _ticker.detach();
+}
+void Ultrasonic::setMode(bool mode)
+{
+ _repeat = mode;
+ if (_repeat) _ticker.attach(this, &Ultrasonic::_ticker_cb, _toVal);
+ else _ticker.detach();
+}
+
+int Ultrasonic::getStatus()
+{
+ return _done;
+}
+void Ultrasonic::clearStatus(void)
+{
+ _done = 0;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Ultrasonic.h Sat Jun 15 20:39:39 2019 +0000
@@ -0,0 +1,40 @@
+#ifndef MBED_ULTRASONIC_H
+#define MBED_ULTRASONIC_H
+
+#include "mbed.h"
+
+class Ultrasonic
+{
+public:
+ Ultrasonic(PinName trigPin, PinName echoPin, float tick = 0.1, bool repeat = false);
+ ~Ultrasonic();
+
+ void trig();
+ int getDistance(void);
+ int getPulseDuration(void);
+
+ //the ultrasonic sensor will stop after measuring once, use clear to clear the value
+ int getStatus(void);
+ void clearStatus(void);
+
+ void pauseMeasure(void);
+ void setMode(bool mode);
+private:
+ DigitalOut _trig;
+ InterruptIn _echo;
+
+ Timer _timer;
+ Ticker _ticker;
+ float _toVal;
+ bool _repeat;
+
+ int _distance;
+ int _pulseDuration;
+
+ void _startT(void);
+ void _endT(void);
+ void _ticker_cb(void);
+ int _done;
+};
+
+#endif MBED_ULTRASONIC_H
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WS2812/WS2812.cpp Sat Jun 15 20:39:39 2019 +0000
@@ -0,0 +1,130 @@
+#include "WS2812.h"
+
+WS2812::WS2812(PinName pin, int size, int zeroHigh, int zeroLow, int oneHigh, int oneLow) : __gpo(pin)
+{
+ __size = size;
+ __transmitBuf = new bool[size * FRAME_SIZE];
+ __use_II = OFF;
+ __II = 0xFF; // set global intensity to full
+ __outPin = pin;
+
+ // Default values designed for K64f. Assumes GPIO toggle takes ~0.4us
+ setDelays(zeroHigh, zeroLow, oneHigh, oneLow);
+}
+
+
+WS2812::~WS2812()
+{
+ delete[] __transmitBuf;
+}
+
+void WS2812::setDelays(int zeroHigh, int zeroLow, int oneHigh, int oneLow) {
+ __zeroHigh = zeroHigh;
+ __zeroLow = zeroLow;
+ __oneHigh = oneHigh;
+ __oneLow = oneLow;
+}
+
+void WS2812::__loadBuf(int buf[],int r_offset, int g_offset, int b_offset) {
+ for (int i = 0; i < __size; i++) {
+ int color = 0;
+
+ color |= ((buf[(i+g_offset)%__size] & 0x0000FF00));
+ color |= ((buf[(i+r_offset)%__size] & 0x00FF0000));
+ color |= (buf[(i+b_offset)%__size] & 0x000000FF);
+ color |= (buf[i] & 0xFF000000);
+
+ // Outut format : GGRRBB
+ // Inout format : IIRRGGBB
+ unsigned char agrb[4] = {0x0, 0x0, 0x0, 0x0};
+
+ unsigned char sf; // scaling factor for II
+
+ // extract colour fields from incoming
+ // 0 = green, 1 = red, 2 = blue, 3 = brightness
+ agrb[0] = (color & 0x0000FF00) >> 8;
+ agrb[1] = (color & 0x00FF0000) >> 16;
+ agrb[2] = color & 0x000000FF;
+ agrb[3] = (color & 0xFF000000) >> 24;
+
+ // set the intensity scaling factor (global, per pixel, none)
+ if (__use_II == GLOBAL) {
+ sf = __II;
+ } else if (__use_II == PER_PIXEL) {
+ sf = agrb[3];
+ } else {
+ sf = 0xFF;
+ }
+
+ // Apply the scaling factor to each othe colour components
+ for (int clr = 0; clr < 3; clr++) {
+ agrb[clr] = ((agrb[clr] * sf) >> 8);
+
+ for (int j = 0; j < 8; j++) {
+ if (((agrb[clr] << j) & 0x80) == 0x80) {
+ // Bit is set (checks MSB fist)
+ __transmitBuf[(i * FRAME_SIZE) + (clr * 8) + j] = 1;
+ } else {
+ // Bit is clear
+ __transmitBuf[(i * FRAME_SIZE) + (clr * 8) + j] = 0;
+ }
+ }
+ }
+ }
+}
+
+void WS2812::write(int buf[]) {
+ write_offsets(buf, 0, 0, 0);
+}
+
+void WS2812::write_offsets (int buf[],int r_offset, int g_offset, int b_offset) {
+ int i, j;
+
+ // Load the transmit buffer
+ __loadBuf(buf, r_offset, g_offset, b_offset);
+
+ // Entering timing critical section, so disabling interrupts
+ __disable_irq();
+
+ // Begin bit-banging
+ for (i = 0; i < FRAME_SIZE * __size; i++) {
+ j = 0;
+ if (__transmitBuf[i]){
+ __gpo = 1;
+ for (; j < __oneHigh; j++) {
+ __nop();
+ }
+ __gpo = 0;
+ for (; j < __oneLow; j++) {
+ __nop();
+ }
+ } else {
+ __gpo = 1;
+ for (; j < __zeroHigh; j++) {
+ __nop();
+ }
+ __gpo = 0;
+ for (; j < __zeroLow; j++) {
+ __nop();
+ }
+ }
+ }
+
+ // Exiting timing critical section, so enabling interrutps
+ __enable_irq();
+}
+
+
+void WS2812::useII(BrightnessControl bc)
+{
+ if (bc > OFF) {
+ __use_II = bc;
+ } else {
+ __use_II = OFF;
+ }
+}
+
+void WS2812::setII(unsigned char II)
+{
+ __II = II;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WS2812/WS2812.h Sat Jun 15 20:39:39 2019 +0000
@@ -0,0 +1,116 @@
+/* Copyright (c) 2012 cstyles, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef WS2812_H
+#define WS2812_H
+
+#include "mbed.h"
+
+#define FRAME_SIZE 24
+
+//!Library for the WS2812 RGB LED with integrated controller
+/*!
+The WS2812 is controller that is built into a range of LEDs
+*/
+class WS2812
+{
+public:
+ enum BrightnessControl { OFF, GLOBAL, PER_PIXEL };
+
+ /**
+ * Constructor
+ *
+ * @param pin Output pin. Connect to "Din" on the first WS2812 in the strip
+ * @param size Number of LEDs in your strip
+ * @param zeroHigh How many NOPs to insert to ensure TOH is properly generated. See library description for more information.
+ * @param zeroLow How many NOPs to insert to ensure TOL is properly generated. See library description for more information.
+ * @param oneHigh How many NOPs to insert to ensure T1H is properly generated. See library description for more information.
+ * @param oneLow How many NOPs to insert to ensure T1L is properly generated. See library description for more information.
+ *
+ */
+ WS2812(PinName pin, int size, int zeroHigh, int zeroLow, int oneHigh, int oneLow);
+
+ /*!
+ Destroys instance.
+ */
+ ~WS2812();
+
+ /**
+ * Sets the timing parameters for the bit-banged signal
+ *
+ * @param zeroHigh How many NOPs to insert to ensure TOH is properly generated. See library description for more information.
+ * @param zeroLow How many NOPs to insert to ensure TOL is properly generated. See library description for more information.
+ * @param oneHigh How many NOPs to insert to ensure T1H is properly generated. See library description for more information.
+ * @param oneLow How many NOPs to insert to ensure T1L is properly generated. See library description for more information.
+ *
+ */
+ void setDelays(int zeroHigh, int zeroLow, int oneHigh, int oneLow);
+
+ /**
+ * Writes the given buffer to the LED strip with the given offsets.
+ * NOTE: This function is timing critical, therefore interrupts are disabled during the transmission section.
+ *
+ * @param buf Pointer to the PixelArray buffer
+ * @param r_offset The offset where each each pixel pulls its red component. Wraps to beginning if end is reached.
+ * @param g_offset The offset where each each pixel pulls its green component. Wraps to beginning if end is reached.
+ * @param b_offset The offset where each each pixel pulls its blue component. Wraps to beginning if end is reached.
+ *
+ */
+ void write_offsets(int buf[], int r_offset = 0, int g_offset = 0, int b_offset = 0);
+
+
+ /**
+ * Writes the given buffer to the LED strip
+ * NOTE: This function is timing critical, therefore interrupts are disabled during the transmission section.
+ *
+ * @param buf Pointer to the PixelArray buffer
+ *
+ */
+ void write(int buf[]);
+
+ /**
+ * Sets the brightness mode
+ *
+ * @param bc The brightness control. Defaults to OFF. Possible values include OFF, GLOBAL, and PER_PIXEL
+ *
+ */
+ void useII(BrightnessControl bc);
+
+ /**
+ * Sets the global brightness level.
+ *
+ * @param II The brightness level. Possible values include 0 - 255 (0x00 - 0xFF).
+ *
+ */
+ void setII(unsigned char II);
+
+
+
+private:
+
+ int __size;
+ int __zeroHigh, __zeroLow, __oneHigh, __oneLow;
+ unsigned char __II;
+ BrightnessControl __use_II;
+ bool *__transmitBuf;
+ void __loadBuf(int buf[],int r_offset=0, int g_offset=0, int b_offset=0);
+ PinName __outPin;
+ DigitalOut __gpo;
+};
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Sat Jun 15 20:39:39 2019 +0000
@@ -0,0 +1,269 @@
+#include "mbed.h"
+#include "ReceiverIR.h"
+#include "TB6612FNG.h"
+#include "Ultrasonic.h"
+
+#include "Adafruit_SSD1306.h"
+#include "Adafruit_GFX.h"
+#include "glcdfont.h"
+#define SSD1306_DISPLAYON 0xAF
+#include "WS2812.h"
+#include "PixelArray.h"
+
+#define WS2812_BUF 150
+#define NUM_COLORS 6
+#define NUM_LEDS_PER_COLOR 10
+
+PixelArray px(WS2812_BUF);
+
+#define button2 18
+
+TB6612FNG motorDriver(D6, A0, A1, D5, A3, A2, A5);
+ReceiverIR ir_rx(D4);
+SPI spi(D11,D12,D13);
+DigitalOut spi_cs(D10,1);
+Ultrasonic ultra(D3, D2);
+WS2812 ws(D7, WS2812_BUF, 7, 15, 10, 15);
+
+I2C i2c(D14, D15);
+Adafruit_SSD1306_I2c oled(i2c, D9, 0x78, 64, 128);
+
+float fPwmPeriod; //모터 주기
+float fPwmPulsewidth; //모터 속도
+RemoteIR::Format format;
+uint8_t buf[32]; //리모컨 입력받는 버퍼
+int num; //리모컨 입력 숫자
+int bitcount, decoded; //리모컨 입력 필요변수
+
+void moveStop(void){
+ motorDriver.motorB_stop();
+ motorDriver.motorA_stop();
+}
+
+void moveBackward(void){
+ motorDriver.motorA_ccw();
+ motorDriver.motorB_ccw();
+}
+
+void moveForward(void){
+ motorDriver.motorA_cw();
+ motorDriver.motorB_cw();
+}
+
+void moveLeft(void){
+ motorDriver.motorA_ccw();
+ motorDriver.motorB_cw();
+ wait(0.1);
+ moveStop();
+}
+
+void moveRight(void){
+ motorDriver.motorA_cw();
+ motorDriver.motorB_ccw();
+ wait(0.1);
+ moveStop();
+}
+
+Timer timer;
+int value; //센서 읽은 값
+int ch = 0; //센서 채널 번호
+
+int sensors[5]; //센서 입력 모아놓은 배열
+int sensormin[5] = {999}; //센서별 최소값
+int sensormax[5] = {0}; //센서별 최대값
+int sensorres[5] = {1}; //센서별 범위값
+int sensors_sum=0;
+int sensors_average=0;
+int position = 0;
+int proportional = 0;
+int last_proportional = 0;
+int derivative = 0;
+int setpoint = 0;
+
+float error_value = 0;
+float max_speed = 0.2;
+float right_speed = 0;
+float left_speed = 0;
+float Kp=0.001;
+float Kd=0.001;
+
+void readvalues(void){
+ for(ch=0;ch<6;ch++){
+ spi_cs = 0;
+ spi.format(16, 0);
+ spi.frequency(2000000);
+ wait_us(2);
+ value = spi.write(ch<<12);
+ value >>= 6;
+ spi_cs = 1;
+ wait_us(21);
+ if(ch>0){
+ if(sensormin[ch-1] > value){sensormin[ch-1] = value;}
+ if(sensormax[ch-1] < value){sensormax[ch-1] = value;}
+ }
+ }
+}
+
+void calibration(void){
+ timer.reset();
+ oled.clearDisplay();
+ oled.setTextCursor(0,0);
+ oled.printf("Calibration Start!\r\n");
+ timer.start();
+ while(timer.read_ms()<5000){
+ moveLeft();
+ readvalues();
+ wait(0.1);
+ }
+
+ oled.clearDisplay();
+ oled.setTextCursor(0,0);
+ oled.printf("!! Calibration Result:\r\n");
+
+ for(ch=0;ch<5;ch++){
+ sensorres[ch] = sensormax[ch] - sensormin[ch];
+ oled.printf("%d: %d, ",ch,sensorres[ch]);
+ if(ch==1 || ch==3) {oled.printf("\r\n");}
+ oled.display();
+ }
+ wait(1);
+}
+
+void readcalibrated(void){
+ for(ch=0;ch<6;ch++){
+ spi_cs = 0;
+ spi.format(16, 0);
+ spi.frequency(2000000);
+ wait_us(2);
+ value = spi.write(ch<<12);
+ value >>= 6;
+ spi_cs = 1;
+ wait_us(21);
+ if(ch>0){
+ sensors[ch-1]=value/sensorres[ch-1] * 1000;
+ sensors_average += sensors[ch-1] * ch * 1000;
+ sensors_sum += sensors[ch-1];
+ }
+ }
+}
+
+void pid_calc(void){
+ position = int(sensors_average / sensors_sum);
+ proportional = position - setpoint;
+ derivative = proportional - last_proportional;
+ last_proportional = proportional;
+ error_value = float(proportional * Kp + derivative * Kd);
+}
+
+void calc_turn(void){
+ if(error_value < -0.1){
+ error_value = -0.1;
+ }
+ if(error_value > 0.1){
+ error_value = 0.1;
+ }
+ if(error_value < 0){
+ right_speed = max_speed + error_value;
+ left_speed = max_speed;
+ }
+ else{
+ right_speed = max_speed;
+ left_speed = max_speed - error_value;
+ }
+}
+
+void motor_drive(void){
+ motorDriver.setPwmApulsewidth(left_speed);
+ motorDriver.setPwmBpulsewidth(right_speed);
+ moveForward();
+}
+
+void loop(void){
+ readcalibrated();
+ pid_calc();
+ calc_turn();
+ motor_drive();
+}
+
+/*
+1 = 12
+2 = 24
+3 = 94
+4 = 8
+5 = 28
+6 = 90
+7 = 66
+8 = 82
+9 = 74
+0 = 22
++100 = 25
++200 = 13
+next = 64
+prev = 68
+vol+ = 21
+vol- = 7
+*/
+int main() {
+ spi_cs = 0; //SPI
+ ultra.trig(); //울트라 소닉 시작
+ ultra.setMode(true); //울트라 소닉 측정시작
+
+ while(1){
+ oled.clearDisplay();
+ oled.setTextCursor(0,0);
+ oled.printf("ls: %f ",left_speed);
+ oled.printf("rs: %f\r\n",right_speed);
+ oled.printf("0: %d, 1: %d\r\n2: %d, 3: %d\r\n4: %d\r\n",sensors[0],sensors[1],sensors[2],sensors[3],sensors[4]);
+ //oled.printf("maxv: %d, minv: %d\r\n",maxv, minv);
+ oled.display();
+
+ readcalibrated();
+ pid_calc();
+
+ //리모컨 입력받기
+ if (ir_rx.getState() == ReceiverIR::Received) {
+ bitcount = ir_rx.getData(&format, buf, sizeof(buf) * 8);
+ if (bitcount>0) {
+ decoded=buf[3];
+ num = buf[2];
+ switch(num){
+ case 24:
+ moveForward();
+ break;
+ case 90:
+ moveRight();
+ break;
+ case 82:
+ moveBackward();
+ break;
+ case 8:
+ moveLeft();
+ break;
+ case 21: //속도상승
+ max_speed+=0.05;
+ break;
+ case 7: //속도저하
+ max_speed-=-0.05;
+ break;
+ case 28:
+ moveStop();
+ break;
+ case 25:
+ calibration();
+ break;
+ case 13:
+ loop();
+ break;
+ }
+ }
+ }
+
+ //장애물 만나면 스탑!!
+ if(ultra.getDistance()<10)
+ {
+ moveBackward();
+ wait(0.01);
+ moveStop();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Sat Jun 15 20:39:39 2019 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400 \ No newline at end of file