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 2:d9745be6c253, committed 2022-08-04
- Comitter:
- fionalin
- Date:
- Thu Aug 04 15:14:29 2022 -0400
- Parent:
- 1:40e5ac1119a6
- Commit message:
- hehe forgot to commit
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Thu Aug 04 15:14:29 2022 -0400 @@ -0,0 +1,5 @@ +^BUILD$ +^.mbed$ +^mbed-os$ +^I2C_Driver$ +^nRF51822$
Binary file .pio/build/nucleo_h743zi/.sconsign38.dblite has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.pio/build/project.checksum Thu Aug 04 15:14:29 2022 -0400 @@ -0,0 +1,1 @@ +69f52b61f982c3fe53fb9cec202912385b539127 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adafruit_MPR121.cpp Thu Aug 04 15:14:29 2022 -0400 @@ -0,0 +1,261 @@ +/*! + * @file Adafruit_MPR121.cpp + * + * @mainpage Adafruit MPR121 arduino driver + * + * @section intro_sec Introduction + * + * This is a library for the MPR121 I2C 12-chan Capacitive Sensor + * + * Designed specifically to work with the MPR121 sensor from Adafruit + * ----> https://www.adafruit.com/products/1982 + * + * These sensors use I2C to communicate, 2+ pins are required to + * interface + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * @section author Author + * + * Written by Limor Fried/Ladyada for Adafruit Industries. + * + * @section license License + * + * BSD license, all text here must be included in any redistribution. + */ + +#include "Adafruit_MPR121.h" + +// uncomment to use autoconfig ! +//#define AUTOCONFIG // use autoconfig (Yes it works pretty well!) + +/*! + * @brief Default constructor + */ +Adafruit_MPR121::Adafruit_MPR121() {} + +/*! + * @brief Begin an MPR121 object on a given I2C bus. This function resets + * the device and writes the default settings. + * @param i2c_addr + * the i2c address the device can be found on. Defaults to 0x5A. + * @param i2c_sda + * SDA pin for I2C + * @param i2c_scl + * SCL pin for I2C + * @param touchThreshold + * touch detection threshold value + * @param releaseThreshold + * release detection threshold value + * @returns true on success, false otherwise + */ +bool Adafruit_MPR121::begin(uint8_t i2c_addr, PinName i2c_sda, PinName i2c_scl, + uint8_t touchThreshold, uint8_t releaseThreshold) { + this->i2c_addr = i2c_addr; + + if (i2c_dev) { + delete i2c_dev; + } + i2c_dev = new I2C(i2c_sda, i2c_scl); + + // soft reset + writeRegister(MPR121_SOFTRESET, 0x63); + wait_us(1000); + for (uint8_t i = 0; i < 0x7F; i++) { + // Serial.print("$"); Serial.print(i, HEX); + // Serial.print(": 0x"); Serial.println(readRegister8(i)); + } + + writeRegister(MPR121_ECR, 0x0); + + uint8_t c = readRegister8(MPR121_CONFIG2); + + if (c != 0x24) + return false; + + setThresholds(touchThreshold, releaseThreshold); + writeRegister(MPR121_MHDR, 0x01); + writeRegister(MPR121_NHDR, 0x01); + writeRegister(MPR121_NCLR, 0x0E); + writeRegister(MPR121_FDLR, 0x00); + + writeRegister(MPR121_MHDF, 0x01); + writeRegister(MPR121_NHDF, 0x05); + writeRegister(MPR121_NCLF, 0x01); + writeRegister(MPR121_FDLF, 0x00); + + writeRegister(MPR121_NHDT, 0x00); + writeRegister(MPR121_NCLT, 0x00); + writeRegister(MPR121_FDLT, 0x00); + + writeRegister(MPR121_DEBOUNCE, 0); + writeRegister(MPR121_CONFIG1, 0x10); // default, 16uA charge current + writeRegister(MPR121_CONFIG2, 0x20); // 0.5uS encoding, 1ms period + +#ifdef AUTOCONFIG + writeRegister(MPR121_AUTOCONFIG0, 0x0B); + + // correct values for Vdd = 3.3V + writeRegister(MPR121_UPLIMIT, 200); // ((Vdd - 0.7)/Vdd) * 256 + writeRegister(MPR121_TARGETLIMIT, 180); // UPLIMIT * 0.9 + writeRegister(MPR121_LOWLIMIT, 130); // UPLIMIT * 0.65 +#endif + + // enable X electrodes and start MPR121 + uint8_t ECR_SETTING = + 0x80 + 12; // 5 bits for baseline tracking & proximity disabled + X + // amount of electrodes running (12) + writeRegister(MPR121_ECR, ECR_SETTING); // start with above ECR setting + + return true; +} + +/*! + * @brief DEPRECATED. Use Adafruit_MPR121::setThresholds(uint8_t touch, + * uint8_t release) instead. + * @param touch + * see Adafruit_MPR121::setThresholds(uint8_t touch, uint8_t + * *release) + * @param release + * see Adafruit_MPR121::setThresholds(uint8_t touch, *uint8_t + * release) + */ +void Adafruit_MPR121::setThreshholds(uint8_t touch, uint8_t release) { + setThresholds(touch, release); +} + +/*! + * @brief Set the touch and release thresholds for all 13 channels on the + * device to the passed values. The threshold is defined as a + * deviation value from the baseline value, so it remains constant + * even baseline value changes. Typically the touch threshold is a little bigger + * than the release threshold to touch debounce and hysteresis. For typical + * touch application, the value can be in range 0x05~0x30 for example. The + * setting of the threshold is depended on the actual application. For the + * operation details and how to set the threshold refer to application note + * AN3892 and MPR121 design guidelines. + * @param touch + * the touch threshold value from 0 to 255. + * @param release + * the release threshold from 0 to 255. + */ +void Adafruit_MPR121::setThresholds(uint8_t touch, uint8_t release) { + // set all thresholds (the same) + for (uint8_t i = 0; i < 12; i++) { + writeRegister(MPR121_TOUCHTH_0 + 2 * i, touch); + writeRegister(MPR121_RELEASETH_0 + 2 * i, release); + } +} + +/*! + * @brief Read the filtered data from channel t. The ADC raw data outputs + * run through 3 levels of digital filtering to filter out the high + * frequency and low frequency noise encountered. For detailed information on + * this filtering see page 6 of the device datasheet. + * @param t + * the channel to read + * @returns the filtered reading as a 10 bit unsigned value + */ +uint16_t Adafruit_MPR121::filteredData(uint8_t t) { + if (t > 12) + return 0; + return readRegister16(MPR121_FILTDATA_0L + t * 2); +} + +/*! + * @brief Read the baseline value for the channel. The 3rd level filtered + * result is internally 10bit but only high 8 bits are readable + * from registers 0x1E~0x2A as the baseline value output for each channel. + * @param t + * the channel to read. + * @returns the baseline data that was read + */ +uint16_t Adafruit_MPR121::baselineData(uint8_t t) { + if (t > 12) + return 0; + uint16_t bl = readRegister8(MPR121_BASELINE_0 + t); + return (bl << 2); +} + +/** + * @brief Read the touch status of all 13 channels as bit values in a 12 + * bit integer. + * @returns a 12 bit integer with each bit corresponding to the touch status + * of a sensor. For example, if bit 0 is set then channel 0 of the + * device is currently deemed to be touched. + */ +uint16_t Adafruit_MPR121::touched(void) { + uint16_t t = readRegister16(MPR121_TOUCHSTATUS_L); + return t & 0x0FFF; +} + +/*! + * @brief Read the contents of an 8 bit device register. + * @param reg the register address to read from + * @returns the 8 bit value that was read. + */ +uint8_t Adafruit_MPR121::readRegister8(uint8_t reg) { + // Adafruit's library sends TWO bytes address. If you have + // only one byte, send it as the first byte and zero the + // second byte. + char reg_addr[2] = {reg, 0x00}; + char value; + i2c_dev->write(i2c_addr, reg_addr, 2); + i2c_dev->read(i2c_addr, &value, 1); + + return value; +} + +/*! + * @brief Read the contents of a 16 bit device register. + * @param reg the register address to read from + * @returns the 16 bit value that was read. + */ +uint16_t Adafruit_MPR121::readRegister16(uint8_t reg) { + // Adafruit's library sends TWO bytes address. If you have + // only one byte, send it as the first byte and zero the + // second byte. + char reg_addr[2] = {reg, 0x00}; + char value[2]; + i2c_dev->write(i2c_addr, reg_addr, 2); + i2c_dev->read(i2c_addr, value, 2); + + // Combine the two bytes into a single value of 16 bits. + return ((uint16_t)value[1] << 8) + (uint16_t)value[0]; +} + +/*! + @brief Writes 8-bits to the specified destination register + @param reg the register address to write to + @param value the value to write +*/ +void Adafruit_MPR121::writeRegister(uint8_t reg, uint8_t value) { + // MPR121 must be put in Stop Mode to write to most registers + bool stop_required = true; + + // first get the current set value of the MPR121_ECR register + uint8_t ecr_backup = readRegister8(MPR121_ECR); + if ((reg == MPR121_ECR) || ((0x73 <= reg) && (reg <= 0x7A))) { + stop_required = false; + } + + if (stop_required) { + // clear this register to set stop mode + writeRegister(MPR121_ECR, 0x00); + } + + // Write to the register by writing the address first then writing + // the intended value for the register + char reg_addr[2] = {reg, 0x00}; // Adafruit's library uses TWO bytes addr (see readRegister8) + i2c_dev->write(i2c_addr, reg_addr, 2); + i2c_dev->write(i2c_addr, (char*)&value, 1); + + if (stop_required) { + // write back the previous set ECR settings + char ecr_addr[2] = {MPR121_ECR, 0x00}; + i2c_dev->write(i2c_addr, ecr_addr, 2); + i2c_dev->write(i2c_addr, (char*)&ecr_backup, 1); + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adafruit_MPR121.h Thu Aug 04 15:14:29 2022 -0400 @@ -0,0 +1,111 @@ +/*! + * @file Adafruit_MPR121.h + * + * This is a library for the MPR121 12-Channel Capacitive Sensor + * + * Designed specifically to work with the MPR121 board. + * + * Pick one up today in the adafruit shop! + * ------> https://www.adafruit.com/product/1982 + * + * These sensors use I2C to communicate, 2+ pins are required to interface + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit andopen-source hardware by purchasing products + * from Adafruit! + * + * Limor Fried/Ladyada (Adafruit Industries). + * + * BSD license, all text above must be included in any redistribution + */ + +#ifndef ADAFRUIT_MPR121_H +#define ADAFRUIT_MPR121_H + +#include <cstdint> +#include <mbed.h> + +// The default I2C address +#define MPR121_I2CADDR_DEFAULT 0x5A ///< default I2C address +#define MPR121_TOUCH_THRESHOLD_DEFAULT 12 ///< default touch threshold value +#define MPR121_RELEASE_THRESHOLD_DEFAULT 6 ///< default relese threshold value + +/*! + * Device register map + */ +enum { + MPR121_TOUCHSTATUS_L = 0x00, + MPR121_TOUCHSTATUS_H = 0x01, + MPR121_FILTDATA_0L = 0x04, + MPR121_FILTDATA_0H = 0x05, + MPR121_BASELINE_0 = 0x1E, + MPR121_MHDR = 0x2B, + MPR121_NHDR = 0x2C, + MPR121_NCLR = 0x2D, + MPR121_FDLR = 0x2E, + MPR121_MHDF = 0x2F, + MPR121_NHDF = 0x30, + MPR121_NCLF = 0x31, + MPR121_FDLF = 0x32, + MPR121_NHDT = 0x33, + MPR121_NCLT = 0x34, + MPR121_FDLT = 0x35, + + MPR121_TOUCHTH_0 = 0x41, + MPR121_RELEASETH_0 = 0x42, + MPR121_DEBOUNCE = 0x5B, + MPR121_CONFIG1 = 0x5C, + MPR121_CONFIG2 = 0x5D, + MPR121_CHARGECURR_0 = 0x5F, + MPR121_CHARGETIME_1 = 0x6C, + MPR121_ECR = 0x5E, + MPR121_AUTOCONFIG0 = 0x7B, + MPR121_AUTOCONFIG1 = 0x7C, + MPR121_UPLIMIT = 0x7D, + MPR121_LOWLIMIT = 0x7E, + MPR121_TARGETLIMIT = 0x7F, + + MPR121_GPIODIR = 0x76, + MPR121_GPIOEN = 0x77, + MPR121_GPIOSET = 0x78, + MPR121_GPIOCLR = 0x79, + MPR121_GPIOTOGGLE = 0x7A, + + MPR121_SOFTRESET = 0x80, +}; + +//.. thru to 0x1C/0x1D + +/*! + * @brief Class that stores state and functions for interacting with MPR121 + * proximity capacitive touch sensor controller. + */ +class Adafruit_MPR121 { +public: + // Hardware I2C + Adafruit_MPR121(); + + bool begin(uint8_t i2c_addr = MPR121_I2CADDR_DEFAULT, + PinName i2c_sda = I2C_SDA, + PinName i2c_scl = I2C_SCL, + uint8_t touchThreshold = MPR121_TOUCH_THRESHOLD_DEFAULT, + uint8_t releaseThreshold = MPR121_RELEASE_THRESHOLD_DEFAULT); + + uint16_t filteredData(uint8_t t); + uint16_t baselineData(uint8_t t); + + uint8_t readRegister8(uint8_t reg); + uint16_t readRegister16(uint8_t reg); + void writeRegister(uint8_t reg, uint8_t value); + uint16_t touched(void); + // Add deprecated attribute so that the compiler shows a warning + void setThreshholds(uint8_t touch, uint8_t release) + __attribute__((deprecated)); + void setThresholds(uint8_t touch, uint8_t release); + +private: + uint8_t i2c_addr; + mbed::I2C* i2c_dev = NULL; +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/actual_main.h Thu Aug 04 15:14:29 2022 -0400 @@ -0,0 +1,136 @@ +#include <cmath> +#include <cstdint> +#include <mbed.h> +#include "stepper.h" +#include "capsense.h" +#include "dis_exp.h" +#include "data_dumper.h" +#include "Adafruit_MPR121.h" + +const PinName MOTOR_ENABLE = D15; +const PinName MOTOR_STEP = D9; +const PinName MOTOR_DIR = D13; +const PinName MOTOR_MS1 = D12; +const PinName MOTOR_MS2 = D11; +const PinName MOTOR_MS3 = D10; +const PinName SLEEP = D1; + +const PinName CS_MEASURE = D2; +const PinName CS_SQUARE = D3; + +const int BAUD_RATE = 9600; + +const int32_t DIS_N_MEASURE = 50; +const uint32_t DIS_T_MEASURE_US = 400; //currently not in use +const int32_t DIS_DELTA_STEPS = 25; +const int32_t DIS_MAX_STEPS = 800; + +enum State { + STOPPED, + UP, + DOWN, + DISCRETE, + CONTINUOUS +}; + +int main(void) { + State curState = State::STOPPED; + + BufferedSerial pc(USBTX, USBRX, BAUD_RATE); + pc.set_blocking(false); + + StepperMotor motor(MOTOR_ENABLE, + MOTOR_STEP, + MOTOR_DIR, + MOTOR_MS1, + MOTOR_MS2, + MOTOR_MS3, + SLEEP); + + // CapSense cap_sense(CS_MEASURE, CS_SQUARE); + + Adafruit_MPR121 mpr121; + + DiscreteExperiment discrete_exp(motor, mpr121, DIS_N_MEASURE, DIS_T_MEASURE_US, + DIS_DELTA_STEPS, DIS_MAX_STEPS); + +// ContinuousExperiment continuous_exp(motor, cap_sense); + + while (true) { + // State behavior + switch (curState) { + case State::STOPPED: + break; + case State::UP: + /* move motor up */ + motor.step_positive(); + break; + case State::DOWN: + /* move motor down */ + motor.step_negative(); + break; + case State::DISCRETE: + /* discrete state behavior */ + discrete_exp.proceed(); + if (discrete_exp.is_done()) { + auto& data = discrete_exp.report(); + printf("Gathered %d data points. Starting data dump...\n", data.size()); + dump_data(data); + curState = State::STOPPED; + } + break; + case State::CONTINUOUS: + /*continuous state behavior */ +// continuous_exp.proceed(); +// if (continuous_exp.is_done()) { +// continuous_exp.report(); +// } + break; + default: + printf("[ERROR, %d] Not a state!\n", __LINE__); + break; + } + + // Switch to next state + char input; + ssize_t len = pc.read(&input, 1); + if (len > 0) { + switch (input) { + case '1': + curState = State::UP; + break; + case '2': + curState = State::DOWN; + break; + case '3': + printf("Starting DISCRETE experiment\n"); + curState = State::DISCRETE; + discrete_exp.reset(); + discrete_exp.start(); + break; + case '4': + curState = State::CONTINUOUS; +// continuous_exp.reset(); +// continuous_exp.start(); + break; + case '0': + printf("Stopping\n"); + if (curState == DISCRETE) { + auto& data = discrete_exp.report(); + printf("Gathered %d data points. Starting data dump...\n", data.size()); + dump_data(data); + discrete_exp.reset(); + } else if (curState == CONTINUOUS) { + // continuous_exp.stop(); +// continuous_exp.report(); + } + curState = State::STOPPED; + break; + default: + printf("[ERROR, %d] Not a command!\n", __LINE__); + break; + } + } + } + return 0; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cap-sense.code-workspace Thu Aug 04 15:14:29 2022 -0400 @@ -0,0 +1,16 @@ +{ + "folders": [ + { + "path": ".." + }, + { + "name": "test", + "path": "../../../PlatformIO/Projects/test" + }, + { + "name": "stepper-motor-test", + "path": "../../../PlatformIO/Projects/stepper-motor-test" + } + ], + "settings": {} +} \ No newline at end of file
--- a/capsense.cpp Tue Jul 12 13:02:25 2022 -0400 +++ b/capsense.cpp Thu Aug 04 15:14:29 2022 -0400 @@ -1,33 +1,39 @@ +#include <cstdint> +#include <cstdio> #include <mbed.h> #include "capsense.h" CapSense::CapSense(PinName measure_pin, PinName square_pin) : cap_sense_measure(measure_pin), square_wave(square_pin), measured_this_cycle(false) {} - -bool CapSense::toggle() { - bool last_signal = square_wave.read(); - square_wave.write(!last_signal); - if (!last_signal) { - measured_this_cycle = false; - timer.start(); - } - return !last_signal; + +void CapSense::start() { + square_wave.write(1); + timer.start(); + + measured_this_cycle = false; +} + +void CapSense::reset() { + square_wave.write(0); + wait_us(10000); } bool CapSense::try_measure() { if (cap_sense_measure.read() == 1 && !measured_this_cycle) { + timer.stop(); - last_measurement = timer.read(); + last_measurement = timer.elapsed_time().count(); measured_this_cycle = true; timer.reset(); return true; + } return false; } -long CapSense::read_measurement() { +uint32_t CapSense::read_measurement() { return last_measurement; }
--- a/capsense.h Tue Jul 12 13:02:25 2022 -0400 +++ b/capsense.h Thu Aug 04 15:14:29 2022 -0400 @@ -20,14 +20,15 @@ public: CapSense(PinName measure_pin, PinName square_pin); - bool toggle(); + void start(); + void reset(); bool try_measure(); - long read_measurement(); + uint32_t read_measurement(); private: DigitalOut square_wave; DigitalIn cap_sense_measure; Timer timer; - long last_measurement; + uint32_t last_measurement; bool measured_this_cycle; }; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/con_exp.cpp Thu Aug 04 15:14:29 2022 -0400 @@ -0,0 +1,23 @@ +#include <cstdint> +#include <cstdio> +#include <mbed.h> +#include "con_exp.h" +#include "capsense.h" +#include "stepper.h" + +bool ContinuousExperiment::is_done() { + return state == DONE; +} + +std::vector<std::tuple<int32_t, uint32_t>>& ContinuousExperiment::report() { + return data; +} + +void ContinuousExperiment::start() { + state = MOVING; + move_counter = delta_steps; +} + +void ContinuousExperiment::reset() { + state = IDLE; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/con_exp.h Thu Aug 04 15:14:29 2022 -0400 @@ -0,0 +1,47 @@ +#pragma once + +#include "stepper.h" +#include "capsense.h" +#include <cstdint> +#include <vector> +#include <tuple> + +class ContinuousExperiment { + public: + ContinuousExperiment(StepperMotor& motor, CapSense& capsense, + int32_t n_measure, uint32_t t_measure_us, + int32_t delta_steps, int32_t max_steps); + void proceed(); + bool is_done(); + /** + * Returns a vector of tuples of (steps, tau in microseconds) + */ + std::vector<std::tuple<int32_t, uint32_t>>& report(); /*steps instead of dis */ + void start(); + void reset(); + + private: + enum State { + IDLE, + MOVING, + MEASURING, + DONE + }; + + private: + StepperMotor& motor; + CapSense& capsense; + + int32_t n_measure; + uint32_t t_measure_us; + int32_t delta_steps; + int32_t max_steps; + + std::vector<std::tuple<int32_t, uint32_t>> data; + State state; + + int32_t move_counter; + int32_t measu_counter; + int32_t steps_taken; + +}; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/data_dumper.cpp Thu Aug 04 15:14:29 2022 -0400 @@ -0,0 +1,14 @@ +#include "data_dumper.h" +#include <algorithm> + +void dump_data(std::vector<std::tuple<int32_t, uint32_t>>& data) { + for (auto& steps_tau_tuple: data) { + printf("%d,%d\n", + std::get<0>(steps_tau_tuple), + std::get<1>(steps_tau_tuple)); + } +}; + +void clear_data(std::vector<std::tuple<int32_t, uint32_t>>& data) { + data.clear(); +}; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/data_dumper.h Thu Aug 04 15:14:29 2022 -0400 @@ -0,0 +1,12 @@ +#pragma once + +#include <mbed.h> +#include <vector> +#include <tuple> + +/** +* Takes data collected from experiment (steps, tau) and sends it over serial. +*/ +void dump_data(std::vector<std::tuple<int32_t, uint32_t>>& data); + +void clear_data(std::vector<std::tuple<int32_t, uint32_t>>& data);
--- a/dis_exp.cpp Tue Jul 12 13:02:25 2022 -0400 +++ b/dis_exp.cpp Thu Aug 04 15:14:29 2022 -0400 @@ -1,19 +1,19 @@ +#include <cstdint> +#include <cstdio> #include <mbed.h> #include "dis_exp.h" -#include "capsense.h" +#include "Adafruit_MPR121.h" #include "stepper.h" -DiscreteExperiment::DiscreteExperiment(StepperMotor& motor, CapSense& capsense, +DiscreteExperiment::DiscreteExperiment(StepperMotor& motor, Adafruit_MPR121& mpr121, int32_t n_measure, uint32_t t_measure_us, int32_t delta_steps, int32_t max_steps) - : motor(motor), capsense(capsense), n_measure(n_measure), + : motor(motor), mpr121(mpr121), n_measure(n_measure), t_measure_us(t_measure_us), delta_steps(delta_steps), max_steps(max_steps), steps_taken(0) {} void DiscreteExperiment::proceed() { - - bool measured = false; - + const int DISCHARGE_TOLERANCE = 5; switch (state) { case State::IDLE: break; @@ -23,10 +23,16 @@ if (move_counter != 0 && steps_taken < max_steps) { if (move_counter < 0) { printf("[bug] Oh shit....\n"); + } motor.step_positive(); + wait_us(100); + printf("motor stepping now\n"); + printf("move_counter %d\n", move_counter); + printf("steps taken %d\n", steps_taken); move_counter--; steps_taken++; } else { + printf("state went to measuring \n"); state = MEASURING; measu_counter = n_measure; } @@ -36,19 +42,22 @@ if (measu_counter < 0) { printf("[bug] Oh shit....\n"); } - while (!measured) { - measured = capsense.try_measure(); - } - data.push_back({steps_taken, capsense.read_measurement()}); + // using channel 11 on adafruit mpr121 + uint32_t tau = mpr121.filteredData(11); + + data.push_back({steps_taken, tau}); measu_counter--; - } else { + + wait_us(DISCHARGE_TOLERANCE*tau); + } else if (steps_taken < max_steps) { state = MOVING; move_counter = delta_steps; + } else { + state = DONE; + steps_taken = 0; // clears the steps_taken counter so that next measure can run } break; } - } - } @@ -56,7 +65,7 @@ return state == DONE; } -std::vector<std::tuple<int32_t, long>>& DiscreteExperiment::report() { +std::vector<std::tuple<int32_t, uint32_t>>& DiscreteExperiment::report() { return data; }
--- a/dis_exp.h Tue Jul 12 13:02:25 2022 -0400 +++ b/dis_exp.h Thu Aug 04 15:14:29 2022 -0400 @@ -2,17 +2,22 @@ #include "stepper.h" #include "capsense.h" +#include <cstdint> #include <vector> #include <tuple> +#include "Adafruit_MPR121.h" class DiscreteExperiment { public: - DiscreteExperiment(StepperMotor& motor, CapSense& capsense, + DiscreteExperiment(StepperMotor& motor, Adafruit_MPR121& mpr121, int32_t n_measure, uint32_t t_measure_us, int32_t delta_steps, int32_t max_steps); void proceed(); bool is_done(); - std::vector<std::tuple<int32_t, long>>& report(); /*steps instead of dis */ + /** + * Returns a vector of tuples of (steps, tau in microseconds) + */ + std::vector<std::tuple<int32_t, uint32_t>>& report(); /*steps instead of dis */ void start(); void reset(); @@ -26,14 +31,14 @@ private: StepperMotor& motor; - CapSense& capsense; + Adafruit_MPR121& mpr121; int32_t n_measure; uint32_t t_measure_us; int32_t delta_steps; int32_t max_steps; - std::vector<std::tuple<int32_t, long>> data; + std::vector<std::tuple<int32_t, uint32_t>> data; State state; int32_t move_counter;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/README Thu Aug 04 15:14:29 2022 -0400 @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/README Thu Aug 04 15:14:29 2022 -0400 @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include <Foo.h> +#include <Bar.h> + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html
--- a/main.cpp Tue Jul 12 13:02:25 2022 -0400 +++ b/main.cpp Thu Aug 04 15:14:29 2022 -0400 @@ -1,11 +1,1 @@ -#define ACTUAL 1 -#define TEST_CAPSENSE 0 -#define TEST_MOTOR 0 - -#if ACTUAL -#include "actual_main.cpp" -#elif TEST_CAPSENSE -#include "test_capsense_main.cpp" -#elif TEST_MOTOR -#include "test_motor_main.cpp" -#endif +#include "actual_main.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platformio.ini Thu Aug 04 15:14:29 2022 -0400 @@ -0,0 +1,13 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nucleo_h743zi] +platform = ststm32 +board = nucleo_h743zi
--- a/stepper.cpp Tue Jul 12 13:02:25 2022 -0400 +++ b/stepper.cpp Thu Aug 04 15:14:29 2022 -0400 @@ -1,3 +1,4 @@ +#include <cstdio> #include <mbed.h> #include "stepper.h" #include <chrono> @@ -8,17 +9,31 @@ PinName dir_pin, PinName ms1_pin, PinName ms2_pin, - PinName ms3_pin - ) - : enable(enable_pin), step(step_pin), dir(dir_pin), ms1(ms1_pin), ms2(ms2_pin), ms3(ms3_pin), - count(0) {enable = 0;} - + PinName ms3_pin, + PinName sleep_pin) + : enable(enable_pin), step(step_pin), dir(dir_pin), ms1(ms1_pin), + ms2(ms2_pin), ms3(ms3_pin), sleep(sleep_pin), count(0) { + enable = 0; + sleep = 1; + step = 0; + } + void StepperMotor::step_positive() { dir = 0; step = 1; - wait_us(40); + + wait_us(40000); + if (step == 1) { + printf("step rise\n"); + }; + if (step == 0){ + printf("step fall, also something is wrong\n"); + }; + step = 0; - wait_us(40); + + wait_us(40000); + printf("one step taken\n"); } void StepperMotor::step_negative() {
--- a/stepper.h Tue Jul 12 13:02:25 2022 -0400 +++ b/stepper.h Thu Aug 04 15:14:29 2022 -0400 @@ -5,7 +5,7 @@ class StepperMotor { public: StepperMotor(PinName enable_pin, PinName step_pin, PinName dir_pin, PinName ms1_pin, PinName ms2_pin, - PinName ms3_pin); + PinName ms3_pin, PinName sleep_pin); void step_positive(); void step_negative(); @@ -19,5 +19,6 @@ DigitalOut ms1; DigitalOut ms2; DigitalOut ms3; + DigitalOut sleep; int32_t count; }; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/README Thu Aug 04 15:14:29 2022 -0400 @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test_capsense_main.h Thu Aug 04 15:14:29 2022 -0400 @@ -0,0 +1,23 @@ +#include "mbed.h" +#include "capsense.h" +#include <cstdio> + +const PinName CS_MEASURE = D2; +const PinName CS_SQUARE = D3; + +// main() runs in its own thread in the OS +int main() +{ + CapSense cap_sense(CS_MEASURE, CS_SQUARE); + + while (true) { + cap_sense.start(); // turn it on + while (!cap_sense.try_measure()) {} + printf("%d\n", cap_sense.read_measurement()); + // we read a value, so safe to turn off + cap_sense.reset(); + wait_us(70000); // wait a bit to discharge + + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test_dis_exp_main.h Thu Aug 04 15:14:29 2022 -0400 @@ -0,0 +1,55 @@ +#include <cstdint> +#include <mbed.h> +#include "dis_exp.h" + +const PinName MOTOR_ENABLE = D15; +const PinName MOTOR_STEP = D9; +const PinName MOTOR_DIR = D13; +const PinName MOTOR_MS1 = D12; +const PinName MOTOR_MS2 = D11; +const PinName MOTOR_MS3 = D10; +const PinName SLEEP = D1; + +const PinName CS_MEASURE = D2; +const PinName CS_SQUARE = D3; + +const int BAUD_RATE = 9600; + +const int32_t N_MEASURE = 4; +const uint32_t T_MEASURE_US = 400; //currently not in use +const int32_t DELTA_STEPS = 20; +const int32_t MAX_STEPS = 100; + +int main(void) { + StepperMotor motor(MOTOR_ENABLE, + MOTOR_STEP, + MOTOR_DIR, + MOTOR_MS1, + MOTOR_MS2, + MOTOR_MS3, + SLEEP); + + CapSense cap_sense(CS_MEASURE, CS_SQUARE); + + DiscreteExperiment discrete_exp(motor, cap_sense, N_MEASURE, T_MEASURE_US, + DELTA_STEPS, MAX_STEPS); + + discrete_exp.reset(); + + discrete_exp.start(); + + int steps = 0; + while(!discrete_exp.is_done()) { + printf("Steps: %d\n", steps); + steps++; + discrete_exp.proceed(); + } + + auto& data = discrete_exp.report(); + + for (auto& steps_tau_tuple: data) { + printf("Steps: %d, Tau: %d\n", + std::get<0>(steps_tau_tuple), + std::get<1>(steps_tau_tuple)); + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test_input_main.h Thu Aug 04 15:14:29 2022 -0400 @@ -0,0 +1,37 @@ +#include <mbed.h> + + + +int main(void) { + BufferedSerial pc(USBTX, USBRX, 9600); + + while (true) { + + // Switch to next state + char input; + ssize_t len = pc.read(&input, 1); + if (len > 0) { + switch (input) { + case '1': + pc.write("u", 1); + break; + case '2': + pc.write("d", 1); + break; + case '3': + pc.write("c", 1); + break; + case '4': + pc.write("i", 1); + break; + case '0': + pc.write("s", 1); + break; + default: + printf("[ERROR, %d] Not a command!\n", __LINE__); + break; + } + } + } + return 0; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test_motor_main.h Thu Aug 04 15:14:29 2022 -0400 @@ -0,0 +1,28 @@ +#include <cstdio> +#include <mbed.h> +#include "stepper.h" + +const PinName MOTOR_ENABLE = D15; +const PinName MOTOR_STEP = D9; +const PinName MOTOR_DIR = D13; +const PinName MOTOR_MS1 = D12; +const PinName MOTOR_MS2 = D11; +const PinName MOTOR_MS3 = D10; +const PinName SLEEP = D1; + + + +int main() { + StepperMotor motor(MOTOR_ENABLE, + MOTOR_STEP, + MOTOR_DIR, + MOTOR_MS1, + MOTOR_MS2, + MOTOR_MS3, + SLEEP); + + + while(1) { + motor.step_positive(); + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test_square_main.h Thu Aug 04 15:14:29 2022 -0400 @@ -0,0 +1,22 @@ +#include <mbed.h> + +const PinName MOTOR_ENABLE = D15; +const PinName MOTOR_STEP = D9; +const PinName MOTOR_DIR = D13; +const PinName MOTOR_MS1 = D12; +const PinName MOTOR_MS2 = D11; +const PinName MOTOR_MS3 = D10; +const PinName SLEEP = D1; + + + +int main() { + DigitalOut step(MOTOR_STEP); + + while (true) { + step.write(1); + wait_us(50000); + step.write(0); + wait_us(40000); + } +} \ No newline at end of file