Wirtek Robotics Workshop / RWR_Utils

RWR_Utils.hxx

Committer:
steliansaracut
Date:
2021-07-26
Revision:
11:2329cb17b332
Parent:
9:6c8dcbfc625a

File content as of revision 11:2329cb17b332:

#pragma once

#include "mbed.h"

// pin assignment
#define ESP_RX      PA_9
#define ESP_TX      PA_10
#define ESP_RESET   PA_12
#define QTR_13      PB_0
#define ESP_CHPD    PB_7
#define DRV_BENBL   PB_6
#define QTR_11      PB_1
#define DRV_BPHASE  PF_0
#define QTR_CTL     PF_1
#define ESP_GPIO0   PA_8
#define DRV_APHASE  PA_11
#define QTR_9       PA_7
#define DRV_AENBL   PA_4
#define QTR_7       PA_3
#define QTR_5       PA_1
#define QTR_3       PA_0

// motor driver PWM frequency
#define PWM_FREQUENCY   32.0e3f
#define PWM_PERIOD      1.0f / PWM_FREQUENCY

// number of sensors on QTR module
#define SENSORS_BAR_SIZE 6
// sensors reading when no line is detected
#define SENSORS_ALL_ONES  ((1 << SENSORS_BAR_SIZE) - 1U)

// hysteresis thresholds for analog sensors
#define QTR_THRESHOLD_HIGH  (uint32_t) 5000U
#define QTR_THRESHOLD_LOW   (uint32_t) 20000U

// PID parameters
#define PID_UPDATE_PERIOD_US          1000
#define PID_SETPOINT                  0.0f
#define PID_DEFAULT_KP                0.6f
// #define PID_DEFAULT_KP                0.25f
#define PID_DEFAULT_KI                0.0f
#define PID_DEFAULT_KD                0.0f
#define NO_LINE_SPEED_MOTOR_A         0.0f
#define NO_LINE_SPEED_MOTOR_B         1.0f

// web interface parameters
#define WEB_ESP_BAUD                115200
#define WEB_RECEIVE_BUFFER_SIZE     1024
#define WEB_SEND_BUFFER_SIZE        2048
#define WEB_RECEIVE_TIMEOUT         10000
#define WEB_ESP_INIT_ATTEMPTS       10
#define WEB_IPD_HEADER_MIN_SIZE     9
#define WEB_SSID                    "RWR_1"
#define WEB_PASSWORD                "RWRWRWRW"
#define WEB_CHANNEL                 "1"
#define WEB_ECN                     "3"
#define WEB_MAX_CONNECTIONS         "1"
#define WEB_HIDDEN                  "0"
#define WEB_AP_IP                   "192.168.0.1"
#define WEB_AP_GATEWAY              "192.168.0.1"
#define WEB_AP_NETMASK              "255.255.255.0"
#define WEB_AP_PORT                 "80"
#define WEB_MOTORS_ENABLED_DEFAULT  0

#define ESP_DEBUG

#define ESP_SEND_AND_PROCESS_STATUS(command, next_state) status = ESPSendCommandAndProcessReply(command);\
  if (status == STATUS_OK)\
  {\
    ESPParserState = next_state;\
  } else\
  if (status < STATUS_PENDING)\
  {\
    serial.printf("ESP command failed: %s\r\n", command );\
    ESPParserState = RESET_ESP;\
  }\

// forward USB serial to ESP serial
// #define ENABLE_PASSTHROUGH

typedef enum {
  STATUS_OK      = 1,
  STATUS_PENDING = 0,
  STATUS_TIMEOUT = -1,
  STATUS_ERROR   = -2
} status_t;

// web interface state type
typedef enum {
  IDLE,
  RESET_ESP,
  WAIT_FOR_READY,
  INIT_SEND_AT,
  INIT_SEND_CWMODE,
  INIT_SEND_CWSAP,
  INIT_SEND_CIPAP,
  INIT_SEND_CIPMUX,
  INIT_SEND_CIPSERVER,
  PARSE_IPD,
  PARSE_REQUEST_BODY,
  GENERATE_WEB_PAGE,
  WAIT_FOR_CIPSEND_READY,
  SEND_PAGE,
  WAIT_FOR_SEND_OK,
  CLOSE_CONNECTION
} state_t;

typedef struct {
  int32_t motorsEnabled;
  int32_t Kp;
  int32_t Ki;
  int32_t Kd;
} web_settings_t;

typedef struct {
  uint32_t digitizedSensorValues;
  uint32_t analogSensorValues[SENSORS_BAR_SIZE];
  uint32_t analogSensorValuesAverage;
} web_status_t;

static state_t ESPParserState = RESET_ESP;
static web_status_t webStatus = {};
static Timer ESPCommunicationTimer;
static char webReceiveBuffer[WEB_RECEIVE_BUFFER_SIZE];
static char webSendBuffer[WEB_SEND_BUFFER_SIZE];
static volatile char *webReceiveBufferPointer = webReceiveBuffer;
static char *webReceiveRequestsData = NULL;
static volatile bool webReceivedData = false;
static volatile bool webReceiveBufferFull = false;
static int webConnectionId = -1;
static int webPayloadSize = -1;
static bool webSendNewCommand = true;
static int32_t espInitAttempts = 1;

void ESPReceiveIRQ();
status_t ESPProcessReply();
status_t ESPSendCommandAndProcessReply(const char *command);
status_t ESPRunStateMachine();

class Motor
{
  public:
    Motor(const PinName &_in1Pin, const PinName &_in2Pin, const bool _brake = false);
    void setSpeed(const float speed);
    void setBrake(const bool _brake);

  private:
    PwmOut in1PWM;
    PwmOut in2PWM;
    bool brake;
};

class QTR
{
  public:
    // QTR CTL pin, array of analog inputs connected to sensor bar, number of pulses applied to CTL pin
    QTR(DigitalOut &_ctl, AnalogIn (&_sensors)[SENSORS_BAR_SIZE], const uint32_t dimPulses = 0);

    // dim sensors by applying pulses on CTL pin
    void dim(const uint32_t pulses);

    // returns digitized sensor values as bits of an uint32_t
    // a bit of 0 means that the corresponding sensor detects a reflective surface
    // index 0 in sensors array corresponds to LSB in returned value
    // uses hysteresis to reduce noise
    uint32_t readSensorsAsDigital();

    // writes raw sensor values to buffer via the pointer argument
    void readSensorsAsAnalog(uint32_t *buffer);

    // return line position as a float between -1.0 (left) and 1.0 (right)
    float readSensorsAsFloat();

    // convert digitized sensor values to float
    float digitizedSensorsToFloat(uint32_t digitizedSensors);

  private:
    DigitalOut &ctl;
    AnalogIn (&sensors)[SENSORS_BAR_SIZE];
    uint32_t lastSensorState;
};