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.
Revision 0:295b7e1c12f3, committed 2021-01-18
- Comitter:
- hudakz
- Date:
- Mon Jan 18 19:51:22 2021 +0000
- Commit message:
- Data acquisition and device control with Scilab.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.gitignore Mon Jan 18 19:51:22 2021 +0000 @@ -0,0 +1,4 @@ +.build +.mbed +projectfiles +*.py*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CONTRIBUTING.md Mon Jan 18 19:51:22 2021 +0000 @@ -0,0 +1,5 @@ +# Contributing to Mbed OS + +Mbed OS is an open-source, device software platform for the Internet of Things. Contributions are an important part of the platform, and our goal is to make it as simple as possible to become a contributor. + +To encourage productive collaboration, as well as robust, consistent and maintainable code, we have a set of guidelines for [contributing to Mbed OS](https://os.mbed.com/docs/mbed-os/latest/contributing/index.html).
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MPU6050.lib Mon Jan 18 19:51:22 2021 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/hudakz/code/MPU6050/#9c2bb0f94c31
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README.md Mon Jan 18 19:51:22 2021 +0000 @@ -0,0 +1,64 @@ + +# Blinky Mbed OS example + +The example project is part of the [Arm Mbed OS Official Examples](https://os.mbed.com/code/) and is the [getting started example for Mbed OS](https://os.mbed.com/docs/mbed-os/v5.14/quick-start/index.html). It contains an application that repeatedly blinks an LED on supported [Mbed boards](https://os.mbed.com/platforms/). + +You can build the project with all supported [Mbed OS build tools](https://os.mbed.com/docs/mbed-os/latest/tools/index.html). However, this example project specifically refers to the command-line interface tool [Arm Mbed CLI](https://github.com/ARMmbed/mbed-cli#installing-mbed-cli). +(Note: To see a rendered example you can import into the Arm Online Compiler, please see our [import quick start](https://os.mbed.com/docs/mbed-os/latest/quick-start/online-with-the-online-compiler.html#importing-the-code).) + +1. [Install Mbed CLI](https://os.mbed.com/docs/mbed-os/latest/quick-start/offline-with-mbed-cli.html). + +1. Clone this repository on your system, and change the current directory to where the project was cloned: + + ```bash + $ git clone git@github.com:armmbed/mbed-os-example-blinky && cd mbed-os-example-blinky + ``` + + Alternatively, you can download the example project with Arm Mbed CLI using the `import` subcommand: + + ```bash + $ mbed import mbed-os-example-blinky && cd mbed-os-example-blinky + ``` + + +## Application functionality + +The `main()` function is the single thread in the application. It toggles the state of a digital output connected to an LED on the board. + +## Building and running + +1. Connect a USB cable between the USB port on the board and the host computer. +2. <a name="build_cmd"></a> Run the following command to build the example project and program the microcontroller flash memory: + ```bash + $ mbed compile -m <TARGET> -t <TOOLCHAIN> --flash + ``` +The binary is located at `./BUILD/<TARGET>/<TOOLCHAIN>/mbed-os-example-blinky.bin`. + +Alternatively, you can manually copy the binary to the board, which you mount on the host computer over USB. + +Depending on the target, you can build the example project with the `GCC_ARM`, `ARM` or `IAR` toolchain. After installing Arm Mbed CLI, run the command below to determine which toolchain supports your target: + +```bash +$ mbed compile -S +``` + +## Expected output +The LED on your target turns on and off every 500 milliseconds. + + +## Troubleshooting +If you have problems, you can review the [documentation](https://os.mbed.com/docs/latest/tutorials/debugging.html) for suggestions on what could be wrong and how to fix it. + +## Related Links + +* [Mbed OS Stats API](https://os.mbed.com/docs/latest/apis/mbed-statistics.html). +* [Mbed OS Configuration](https://os.mbed.com/docs/latest/reference/configuration.html). +* [Mbed OS Serial Communication](https://os.mbed.com/docs/latest/tutorials/serial-communication.html). +* [Mbed OS bare metal](https://os.mbed.com/docs/mbed-os/latest/reference/mbed-os-bare-metal.html). +* [Mbed boards](https://os.mbed.com/platforms/). + +### License and contributions + +The software is provided under Apache-2.0 license. Contributions to this project are accepted under the same license. Please see contributing.md for more info. + +This project contains code from other projects. The original license text is included in those source files. They must comply with our license guide.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ScilabSerial/DcMotor.cpp Mon Jan 18 19:51:22 2021 +0000
@@ -0,0 +1,66 @@
+#include "DcMotor.h"
+
+/**
+ * @brief The DcMotor class
+ * @note Driven by L293 or L298
+ */
+DcMotor::DcMotor(PinName pin1, PinName pin2, int driverType) :
+ _driverType(driverType)
+{
+ _pwmOut1 = new PwmOut(pin1);
+ _pwmOut1->write(0);
+ switch (_driverType) {
+ case 0: //L293
+ _pwmOut2 = new PwmOut(pin2);
+ _pwmOut2->write(0);
+ break;
+
+ case 1: //L297
+ _digitalOut2 = new DigitalOut(pin2);
+ _digitalOut2->write(0);
+ break;
+ }
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+DcMotor::~DcMotor()
+{
+ delete _pwmOut1;
+ delete _pwmOut2;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void DcMotor::run(int direction, float speed)
+{
+ switch (_driverType) {
+ case 0: //L293
+ if (direction == 0) {
+ _pwmOut1->write(0);
+ _pwmOut2->write(speed);
+ }
+ else {
+ _pwmOut1->write(speed);
+ _pwmOut2->write(0);
+ }
+ break;
+
+ case 1: //L297
+ if (direction == 0)
+ _digitalOut2->write(0);
+ else
+ _digitalOut2->write(1);
+
+ _pwmOut1->write(speed);
+ break;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ScilabSerial/DcMotor.h Mon Jan 18 19:51:22 2021 +0000
@@ -0,0 +1,18 @@
+#ifndef DCMOTOR_H
+#define DCMOTOR_H
+
+#include "mbed.h"
+
+class DcMotor
+{
+ PwmOut* _pwmOut1;
+ PwmOut* _pwmOut2;
+ DigitalOut* _digitalOut2;
+ int _driverType;
+public:
+ DcMotor(PinName pin1, PinName pin2, int driverType);
+ ~DcMotor();
+ void run(int direction, float speed);
+};
+
+#endif // DCMOTOR_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ScilabSerial/Encoder.cpp Mon Jan 18 19:51:22 2021 +0000
@@ -0,0 +1,65 @@
+#include "Encoder.h"
+
+/**
+ * @brief The Encoder class
+ * @note Rotary encoder with three operating modes
+ */
+Encoder::Encoder(PinName pinA, PinName pinB, int mode) : _position(0)
+{
+ switch (mode) {
+ case 1:
+ _chanA = new InterruptIn(pinA);
+ _chanA->rise(callback(this, &Encoder::onRiseMode1));
+ _chanB = new InterruptIn(pinB);
+ break;
+
+ case 2:
+ _chanA = new InterruptIn(pinA);
+ _chanA->rise(callback(this, &Encoder::onChangeMode2));
+ _chanA->fall(callback(this, &Encoder::onChangeMode2));
+ _chanB = new InterruptIn(pinB);
+ break;
+
+ case 4:
+ _chanA = new InterruptIn(pinA);
+ _chanA->rise(callback(this, &Encoder::onChangeMode2));
+ _chanA->fall(callback(this, &Encoder::onChangeMode2));
+ _chanB = new InterruptIn(pinB);
+ _chanB->rise(callback(this, &Encoder::onChangeMode2));
+ _chanB->fall(callback(this, &Encoder::onChangeMode2));
+ break;
+ }
+}
+
+Encoder::~Encoder()
+{
+ delete _chanA;
+ delete _chanB;
+}
+
+void Encoder::onRiseMode1()
+{
+ int b = _chanB->read();
+ if (b)
+ _position--;
+ else
+ _position++;
+}
+void Encoder::onChangeMode2()
+{
+ int a = _chanA->read();
+ int b = _chanB->read();
+ if ((a && !b) || (!a && b))
+ _position++;
+ else
+ _position--;
+}
+void Encoder::onChangeMode4()
+{
+ int a = _chanA->read();
+ int b = _chanB->read();
+ if ((a && !b) || (!a && b))
+ _position++;
+ else
+ _position--;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ScilabSerial/Encoder.h Mon Jan 18 19:51:22 2021 +0000
@@ -0,0 +1,20 @@
+#ifndef ENCODER_H
+#define ENCODER_H
+
+#include "mbed.h"
+
+class Encoder
+{
+ InterruptIn* _chanA;
+ InterruptIn* _chanB;
+ int8_t _position;
+public:
+ Encoder(PinName pinA, PinName pinB, int mode);
+ ~Encoder();
+ int8_t position() { return _position; }
+ void reset() { _position = 0; }
+ void onRiseMode1();
+ void onChangeMode2();
+ void onChangeMode4();
+};
+#endif // ENCODER_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ScilabSerial/IntrInCounter.cpp Mon Jan 18 19:51:22 2021 +0000
@@ -0,0 +1,6 @@
+#include "IntrInCounter.h"
+
+IntrInCounter::IntrInCounter(PinName pin) : _value(0), _interruptIn(new InterruptIn(pin))
+{
+ _interruptIn->rise(callback(this, &IntrInCounter::inc));
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ScilabSerial/IntrInCounter.h Mon Jan 18 19:51:22 2021 +0000
@@ -0,0 +1,21 @@
+#ifndef INTRINCOUNTER_H
+#define INTRINCOUNTER_H
+
+#include "mbed.h"
+
+/**
+ * @brief The IntInCounter class
+ * @note Incremented on rising edge of input signal connected to InterruptIn pin
+ */
+class IntrInCounter
+{
+ uint8_t _value;
+ InterruptIn* _interruptIn;
+public:
+ IntrInCounter(PinName pin);
+ void inc() { _value++; }
+ void reset() { _value = 0; }
+ uint8_t read() { return _value; }
+ void activate(PinName pin) { }
+};
+#endif // INTINCOUNTER_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ScilabSerial/ScilabSerial.cpp Mon Jan 18 19:51:22 2021 +0000
@@ -0,0 +1,583 @@
+#include "ScilabSerial.h"
+
+extern UnbufferedSerial dbgPort;
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+ScilabSerial::ScilabSerial(PinName tx, PinName rx, int baud /*= 115200*/ ) :
+ SerialBase(tx, rx, baud),
+ _rxComplete(false),
+ _rxBufLen(0),
+ _rxDataLen(0),
+ _deltaT(0),
+ _mpu6050Available(false)
+{
+ attach(callback(this, &ScilabSerial::onRx));
+
+ // Analog inputs
+ for (size_t i = 0; i < sizeof(_analogPinName) / sizeof(*_analogPinName); i++) {
+ // indexes -> pin names
+ if (_analogPinName[i] != NC)
+ _analogIns[i] = new AnalogIn(_analogPinName[i]);
+ else
+ _analogIns[i] = NULL;
+ }
+
+ // PWM outputs
+ for (size_t i = 0; i < 4; i++) {
+ // indexes 0 to 3 -> pin names D4 to D7
+ if (_digitalPinName[i + 4] != NC)
+ _pwmOuts[i] = new PwmOut(_digitalPinName[i + 4]);
+ else
+ _pwmOuts[i] = NULL;
+ }
+
+ // Digital read write
+ for (size_t i = 0; i < sizeof(_digitalInOuts) / sizeof(*_digitalInOuts); i++)
+ _digitalInOuts[i] = NULL;
+
+ // Servo
+ for (size_t i = 0; i < sizeof(_servos) / sizeof(*_servos); i++)
+ _servos[i] = NULL;
+
+ // MPU6050
+ _mpu6050 = NULL;
+
+ // Interrup-in counters
+ for (size_t i = 0; i < sizeof(_intrInCounters) / sizeof(*_intrInCounters); i++)
+ _intrInCounters[i] = NULL;
+
+ // DC motors
+ for (size_t i = 0; i < sizeof(_dcMotors) / sizeof(*_dcMotors); i++)
+ _dcMotors[i] = NULL;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void ScilabSerial::onRx()
+{
+ // If the '\n' character was used as 'packet-end' delimiter then we could have:
+ //
+ // while (readable()) {
+ // volatile char c = _base_getc();
+ // if (c != '\n') {
+ // if (rxBufLen >= RX_MAX)
+ // rxBufLen = 0; // rxBuf overflow
+ // rxBuf[rxBufLen++] = c;
+ // }
+ // else {
+ // // packet complete
+ // memset(rxData, 0, RX_MAX); // clear rxData
+ // memcpy(rxData, rxBuf, rxBufLen); // copy rxBuf to rxData
+ // rxDataLen = rxBufLen; // set rxData length
+ // memset(rxBuf, 0, RX_MAX); // clear rxBuf
+ // rxBufLen = 0;
+ // }
+ // }
+ // Unfortunately there is neither packet length information in the packet
+ // nor 'packet-end' delimiter is used.
+ // That's why we have to figure out the packet length on the fly based on it's content:
+ volatile char c = _base_getc(); // Read a byte from UART
+
+ _rxBuf[_rxBufLen++] = c; // Store the byte in the receive buffer
+
+ switch (_rxBuf[0]) {
+ case 'A': // Analog read
+ case 'G': // MPU6050
+ case 'R': // Revision request
+ if (_rxBufLen == 2)
+ _rxComplete = true;
+ break;
+
+ case 'W': // PWM (analog) write
+ case 'I': // Interrupt-in counter
+ if (_rxBufLen == 3)
+ _rxComplete = true;
+ break;
+
+ case 'D': // Digital read/write
+ if (_rxBufLen == 3)
+ if (_rxBuf[1] == 'r')
+ _rxComplete = true;
+ break;
+
+ case 'S': // Servo motor
+ if (_rxBufLen == 3)
+ if (_rxBuf[1] != 'w')
+ _rxComplete = true;
+ break;
+
+ case 'E': // Encoder
+ if (_rxBufLen == 3)
+ if (_rxBuf[1] != 'a')
+ _rxComplete = true;
+ break;
+
+ case 'C':
+ if (_rxBufLen == 5)
+ _rxComplete = true;
+
+ case 'M': // DC motor
+ if (_rxBufLen == 3)
+ if (_rxBuf[1] == 'r')
+ _rxComplete = true;
+ break;
+ }
+
+ if ((_rxBuf[0] != 'C') && (_rxBufLen == 4))
+ _rxComplete = true;
+
+ if (_rxComplete) {
+ _rxComplete = false;
+ memset(_rxData, 0, RX_MAX); // reset rxData
+ memcpy(_rxData, _rxBuf, _rxBufLen); // copy rxBuf to rxData
+ _rxDataLen = _rxBufLen; // set rxData length
+ memset(_rxBuf, 0, RX_MAX); // reset rxBuf
+ _rxBufLen = 0;
+ }
+
+// dbgPort.write((void*)(& _rxData), _rxDataLen);
+// dbgPort.write("\r\n", 2);
+
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+ssize_t ScilabSerial::write(const void* buffer, size_t length)
+{
+ const char* ptr = (const char*)buffer;
+ const char* end = ptr + length;
+
+ lock();
+ while (ptr != end) {
+ _base_putc(*ptr++);
+ }
+
+ unlock();
+
+ return ptr - (const char*)buffer;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void ScilabSerial::run()
+{
+ while (1) {
+ if (_mpu6050Available)
+ mpu6050UpdateData();
+
+ if (_rxDataLen > 0) {
+ _rxDataLen = 0;
+ switch (_rxData[0]) {
+ case 'A': // Analog read
+ analogRead();
+ break;
+
+ case 'W': // PWM (analog) write
+ pwmWrite();
+ break;
+
+ case 'D': // Digital
+ digitalReadWrite();
+ break;
+
+ case 'S': // Servo motor
+ servo();
+ break;
+
+ case 'G': // MPU6050
+ mpu6050();
+ break;
+
+ case 'I': // Interrupt-in counter
+ intrInCounter();
+ break;
+
+ case 'E': // Encoder
+ encoder();
+ break;
+
+ case 'C': // DC motor init
+ dcMotorInit();
+ break;
+
+ case 'M': // DC motor
+ dcMotor();
+ break;
+
+ case 'R': // Revision
+ revision();
+ break;
+ }
+ }
+ }
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void ScilabSerial::analogRead()
+{
+ int pin = _rxData[1] - '0'; // analog pin number 0 .. 5
+ uint8_t i = pin; // index of corresponding analogIn 0 .. 5
+
+ if ((pin >= 0 && pin <= 5) && (_analogIns[i] != NULL)) {
+ uint16_t word = _analogIns[i]->read_u16(); // get decimal value 0 .. 65535
+ float val = word / 64.0f; // map 16bit range to 10bit range
+
+ word = round(val);
+ write((uint8_t*) &word, sizeof(uint16_t)); // send it to Scilab
+ }
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void ScilabSerial::pwmWrite()
+{
+ int pin = _rxData[1] - '0'; // digital pin number 4 .. 7
+ uint8_t i = pin - 4; // index of corresponding analogOut (PWMOut) 0 .. 3
+
+ if ((pin >= 4 && pin <= 7) && (_pwmOuts[i] != NULL)) {
+ uint8_t val = _rxData[2]; // the duty cycle: between 0 (always off) and 255 (always on)
+ float dutyCycle = (float)val / 255.0f; // 0.0f (representing on 0%) and 1.0f (representing on 100%)
+
+ _pwmOuts[i]->write(dutyCycle);
+ }
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void ScilabSerial::digitalReadWrite()
+{
+ int pin = _rxData[2] - '0'; // digital pin number 8 .. 13
+ uint8_t i = pin - 8; // index of corresponding digitalInOut 0 .. 7
+
+ if ((pin >= 8 && pin <= 13) && (_digitalPinName[pin] != NC)) {
+ char cmd = _rxData[1]; // command
+ PinDirection pinDirection; // pin direction (PIN_INPUT, PIN_OUTPUT)
+ char c;
+ uint8_t val;
+
+ switch (cmd) {
+ case 'a': // 'a'-> activate
+ pinDirection = (PinDirection) (_rxData[3] - '0');
+ if (_digitalInOuts[i] != NULL)
+ delete _digitalInOuts[i];
+ _digitalInOuts[i] = new DigitalInOut(_digitalPinName[pin], pinDirection, PullUp, 0);
+ break;
+
+ case 'r': // 'r'-> read
+ c = _digitalInOuts[i]->read() + '0';
+ write((uint8_t*) &c, 1);
+ break;
+
+ case 'w': // 'w'-> write
+ val = _rxData[3] - '0';
+
+ if (val == 0 || val == 1)
+ _digitalInOuts[i]->write(val);
+ break;
+ }
+ }
+ else
+ _digitalInOuts[i] = NULL;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void ScilabSerial::servo()
+{
+ int pin = _rxData[2] - '0' + 1; // digital pin number 2 .. 3
+ uint8_t i = pin - 2; // index of corresponding servo 0 .. 1
+ uint8_t val;
+
+ if ((pin == 2 || pin == 3) && (_digitalPinName[pin] != NC)) {
+ char cmd = _rxData[1];
+ switch (cmd) {
+ case 'a': // 'a' -> activate servo
+ if (_servos[i] != NULL)
+ delete _servos[i];
+ _servos[i] = new Servo(_digitalPinName[pin]);
+ break;
+
+ case 'd': // 'd'-> delete servo
+ delete _servos[i];
+ _servos[i] = NULL;
+ break;
+
+ case 'w': // 'w'-> write to servo position in degree (0 .. 180)
+ val = _rxData[3];
+ if (val >= 0 && val <= 180)
+ _servos[i]->position(val);
+ break;
+ }
+ }
+ else
+ _servos[i] = NULL;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void ScilabSerial::mpu6050()
+{
+ uint8_t cmd = _rxData[1];
+ uint16_t data[9];
+
+ if (I2C_SCL != NC && I2C_SDA != NC) {
+ switch (cmd) {
+ case 'a': // 'a'-> acivate
+ if (_mpu6050 != NULL)
+ delete _mpu6050;
+ _mpu6050 = new MPU6050();
+ _mpu6050Available = _mpu6050->init();
+ _mpu6050Timer.start();
+ break;
+
+ case 't': // 't' -> test
+ if (_mpu6050->selfTestOK()) {
+ _mpu6050->reset(); // Reset registers to default in preparation for device calibration
+ _mpu6050->calibrate(); // Calibrate gyro and accelerometers, load biases in bias registers
+ _mpu6050Available = _mpu6050->init();
+ _mpu6050Timer.reset();
+ _mpu6050Timer.start();
+ write("OK", 2);
+ }
+ else {
+ _mpu6050Available = false;
+ write("KO", 2);
+ }
+ break;
+
+ case 'r': // 'r'-> read
+ if (_mpu6050Available) {
+ data[0] = _mpu6050->yaw();
+ data[1] = _mpu6050->pitch();
+ data[2] = _mpu6050->roll();
+ data[3] = _mpu6050->accelX;
+ data[4] = _mpu6050->accelY;
+ data[5] = _mpu6050->accelZ;
+ data[6] = _mpu6050->gyroX;
+ data[7] = _mpu6050->gyroY;
+ data[8] = _mpu6050->gyroZ;
+ write(data, sizeof(data)); // send data to scilab
+ }
+ break;
+ }
+ }
+ else
+ _mpu6050 = NULL;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void ScilabSerial::mpu6050UpdateData()
+{
+ // check if data is available after interrupt
+
+ if (_mpu6050->dataReady()) {
+ _mpu6050->accel();
+ _mpu6050->gyro();
+
+ uint32_t _now = _mpu6050Timer.read_us();
+ _mpu6050Timer.reset();
+
+ float _deltaT = float(_now / 1e-6); // set integration time in seconds
+
+ _mpu6050->madgwickFilter(_deltaT); // apply filter to estimate yaw, pitch and roll
+ }
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void ScilabSerial::intrInCounter()
+{
+ int pin = _rxData[2] - '0'; // digital pin number 8 .. 13
+ uint8_t i = pin - 8; // index of corresonding IntCounter 0 .. 7
+
+ if ((pin >= 8 && pin <= 13) && (_digitalPinName[pin] != NC)) {
+ uint8_t val;
+ char cmd = _rxData[1];
+ switch (cmd) {
+ case 'a': // 'a' -> activate a counter
+ if (_intrInCounters[i] != NULL)
+ delete _intrInCounters[i];
+ _intrInCounters[i] = new IntrInCounter(_digitalPinName[pin]);
+ break;
+
+ case 'p': // 'p' -> get position of a counter
+ val = _intrInCounters[i]->read();
+ write(&val, 1); // send value to scilab (0 .. 256)
+ break;
+
+ case 'r': // 'r' -> release an interrupt counter
+ delete _intrInCounters[i];
+ break;
+
+ case 'z': // 'z' -> set to zero (reset) a counter
+ _intrInCounters[i]->reset();
+ break;
+ }
+ }
+ else
+ _intrInCounters[i] = NULL;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void ScilabSerial::encoder()
+{
+ uint8_t i = _rxData[2] - '0'; // encoder index 0 .. 1
+
+ if ((i >= 0 && i <= 1) && (_digitalPinName[i])) {
+ int pinA, pinB;
+ int8_t pos;
+ int mode;
+ char cmd = _rxData[1]; // command
+
+ switch (cmd) {
+ case 'a': // 'a' -> activate an encoder
+ i == 0 ? pinA = 8 : pinA = 10;
+ pinB = pinA + 1; // pinB -> 9 or 11
+ mode = _rxData[3] - '0'; // '1' -> up chanA, '2' -> up/down chanA, '4' -> up/down chanA and chanB
+ if (_encoders[i] != NULL)
+ delete _encoders[i];
+ _encoders[i] = new Encoder(_digitalPinName[pinA], _digitalPinName[pinB], mode);
+ break;
+
+ case 'p': // 'p' -> get position of an encoder
+ pos = _encoders[i]->position();
+
+ write(&pos, 1); // send value to scilab (0 .. 256)
+ break;
+
+ case 'r': // 'r' -> release an encoder
+ delete _encoders[i];
+ break;
+
+ case 'z': // 'z' -> set to zero (reset) the position of an encoder
+ _encoders[i]->reset();
+ break;
+ }
+ }
+ else
+ _encoders[i] = NULL;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void ScilabSerial::dcMotorInit()
+{
+ uint8_t pin1, pin2;
+ uint8_t driverType;
+ uint8_t i = _rxData[1] - '0'; // motor index
+
+ if ((i < 2) && (_digitalPinName[i] != NC)) {
+ pin1 = _rxData[2]; // pin1 is 2 or 4
+ if (pin1 == 2 || pin1 == 4) {
+ pin2 = _rxData[3] - '0'; // pin2 is 3 or 5
+ if (pin2 == 3 || pin2 == 5) {
+ driverType = _rxData[4] - '0'; // driver: 0 -> L293, 1 -> L298
+ if (driverType >= 0 && driverType <= 1) {
+ if (_dcMotors[i] != NULL)
+ delete _dcMotors[i];
+ _dcMotors[i] = new DcMotor(_digitalPinName[pin1], _digitalPinName[pin2], driverType);
+ write("OK", 2); // tell scilab that motor initialization is complete
+ }
+ }
+ }
+ }
+ else
+ _dcMotors[i] = NULL;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void ScilabSerial::dcMotor()
+{
+ int pin1, pin2;
+ int mode;
+ char cmd;
+ float speed;
+ uint8_t i = _rxData[1] - '0'; // motor index
+
+ if ((i < 2) && (_dcMotors[i] != NULL)) {
+ cmd = _rxData[2] - '0'; // direction of rotation or release
+ switch (cmd) {
+ case 0: // clockwise
+ case 1: // counter clockwise
+ speed = _rxData[3]; // speed
+ _dcMotors[i]->run(cmd, speed);
+ break;
+
+ case 'r': // release
+ delete _dcMotors[i];
+ break;
+ }
+ }
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void ScilabSerial::revision()
+{
+ write("v5", 2);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ScilabSerial/ScilabSerial.h Mon Jan 18 19:51:22 2021 +0000
@@ -0,0 +1,103 @@
+#ifndef SCILABSERIAL_H
+#define SCILABSERIAL_H
+
+#include "mbed.h"
+#include "Servo.h"
+#include "IntrInCounter.h"
+#include "Encoder.h"
+#include "DcMotor.h"
+#include "MPU6050.h"
+
+//#define USBSERIAL
+#define RX_MAX 64
+
+#ifdef USBSERIAL
+#include "USBSerial.h"
+//#include "stm32f103c8t6.h"
+#endif
+/**
+ * @brief The PcSerial class
+ * @note For serial communication with PC
+ */
+#ifdef USBSERIAL
+class PcSerial :
+ public USBSerial
+{
+public:
+ PcSerial() :
+ USBSerial(0x1f00, 0x2012, 0x0001, false)
+ {
+ rxDataLen = 0;
+ attach(this, &PcSerial::onRx);
+ }
+
+ void onRx()
+ {
+ memset(rxData, 0, RX_MAX);
+ while (available()) {
+ char c = _getc();
+ if (c != '\n') {
+ if (rxDataLen >= RX_MAX)
+ rxDataLen = 0; // rxBuf overflow
+ rxData[rxDataLen++] = c;
+ }
+ }
+ }
+
+ ssize_t write(const void* buffer, size_t length) { return writeBlock((uint8_t*)buffer, length); }
+ char rxData[RX_MAX];
+ volatile size_t rxDataLen;
+};
+#else
+class ScilabSerial :
+ public SerialBase
+{
+ bool _rxComplete;
+ char _rxBuf[RX_MAX];
+ volatile size_t _rxBufLen;
+ char _rxData[RX_MAX];
+ volatile size_t _rxDataLen;
+
+#if defined(TARGET_BLUEPILL)
+ PinName _digitalPinName[16] = { NC, NC, D2, D3, D4, D5, D6, D7, D8, NC, D10, D11, D12, D13, D14, D15 };
+ PinName _analogPinName[6] = { A0, A1, A2, A3, NC, NC };
+#elif defined(TARGET_BLACKPILL)
+ PinName _digitalPinName[16] = { NC, NC, D2, D3, D4, D5, D6, D7, D8, NC, D10, D11, D12, D13, D14, D15 };
+ PinName _analogPinName[6] = { A0, A1, A2, A3, NC, NC };
+#else
+ PinName _digitalPinName[16] = { NC, NC, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15 };
+ PinName _analogPinName[6] = { A0, A1, A2, A3, A4, A5 };
+#endif
+ DigitalInOut* _digitalInOuts[8];
+ AnalogIn* _analogIns[6];
+ PwmOut* _pwmOuts[4];
+ IntrInCounter* _intrInCounters[8];
+ Servo* _servos[2];
+ Encoder* _encoders[2];
+ DcMotor* _dcMotors[2];
+ MPU6050* _mpu6050;
+ Timer _mpu6050Timer;
+ uint32_t _now;
+ float _deltaT;
+ bool _mpu6050Available;
+public:
+
+ ScilabSerial(PinName tx, PinName rx, int baud = 115200);
+
+ void run();
+ void onRx();
+ ssize_t write(const void* buffer, size_t length);
+ void analogRead();
+ void pwmWrite();
+ void digitalReadWrite();
+ void servo();
+ void mpu6050();
+ void intrInCounter();
+ void encoder();
+ void dcMotorInit();
+ void dcMotor();
+ void revision();
+ void mpu6050UpdateData();
+};
+#endif
+#endif // SCILABSERIAL_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Servo.lib Mon Jan 18 19:51:22 2021 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/simon/code/Servo/#36b69a7ced07
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Mon Jan 18 19:51:22 2021 +0000
@@ -0,0 +1,15 @@
+#include "mbed.h"
+#include "ScilabSerial.h"
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+int main()
+{
+ ScilabSerial scilab(USBTX, USBRX);
+
+ scilab.run();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os.lib Mon Jan 18 19:51:22 2021 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#f2278567d09b9ae9f4843e1d9d393526b9462783
Binary file resources/official_armmbed_example_badge.png has changed