Hi All,
First post after reading the forum rules but please let me know if I have missed anything!
My current project is using a Nano 33 BLE as a peripheral, which monitors changes to two characteristics and uses them to calculate 6 outputs to three motors. Each motor requires a PWM input for speed and a digital (High or Low) input for direction. Since the Nano is 3.3v only and the motors require a 5v input I have used a logic level shifter to allow communication. 12v is also provided to the motors to allow them to run.
When I tested the motors with a simple sketch running three motors one direction from 0 to 255 and back to 0 then changing direction and repeating I had no issues. However when I then built on this code to add the BLE elements, see full code at bottom of the post, I was unable to have the motors turn when the central connects to the peripheral. I measured the outputs on my scope and the code does what it is meant to be doing i.e. as the characteristic values are changed the PWM and digital outputs alter. What I did notice though is there is a regular spike on the digitalWrite pins, this spike is high when the pin is pulled low and is low when the pin is pulled high, the spike is also always either to ground or to vcc.
As soon as the peripheral is disconnected from the central, the spikes go away, I also noticed removing the logic level converter removes the spikes when measuring the Nano pins. I also tried to use analogWrite instead sending a max or min value but this just crashes the OS on connection to the peripheral.
Taking a closer look on the scope, see pictures attached, there are two spikes roughly 3.8us each in duration with a 2.4us gap between them which are repeated with a frequency of roughly 3kHz.
I am unsure if this is the logic level conversion or the BLE and am hoping someone with more knowledge could possibly suggest some additional tests I can conduct or suggest something else to try.
Component details are below;
Motors = FIT0441 Brushless DC Motor
Logic level shifters = SparkFun Bidirectional Shifter part number 12009
/*
* Title - motor test peripheral
* Author - O Smith
* Date - 08/02/2020
* Version 1.0
* Description - Test script for the wheel, sets up peripheral device with one service and two characteristics, one for wheel direction
* the other for wheel speed. The program then calculates the required output to three motors and sends the signals to the appropraite
* pins for the motors.
*
*/
// Libraries
#include <ArduinoBLE.h>; // BLE library
#include <BasicLinearAlgebra.h> // matrix library
// Variables
float motor1Matrix = 0; // matrix output for motor 1
float motor2Matrix = 0; // matrix output for motor 2
float motor3Matrix = 0; // matrix output for motor 3
int motor1PWM = 0; // pwm inpupt for Motor 1
int motor2PWM = 0; // pwm inpupt for Motor 2
int motor3PWM = 0; // pwm inpupt for Motor 3
byte Ax = 100; // input value from controller for x
byte Ay = 100; // input value for controller for y
// Matricies
BLA::Matrix<3,3> wheelMatrix = {-0.333, 0.577, 0.333,//generate matrix for motor offsets
-0.333, -0.577, 0.333,
0.666, 0, 0.333};
// BLE Setup
BLEService wheel("5c15fae4-28e5-11ea-978f-2e728ce88125"); // set up wheel service
BLEByteCharacteristic wheelx ("5c15fe68-28e5-11ea-978f-2e728ce88125", BLERead|BLEWrite); // set up wheel speed characteristic
BLEByteCharacteristic wheely ("5c15fd1e-28e5-11ea-978f-2e728ce88125", BLERead|BLEWrite); // set up wheel direction characteristic
void motorControl(byte xaxis, byte yaxis){ // motor control function, takes wheel vectors and translates to motor speed and direction
Serial.println("x and y values are");
Serial.print(xaxis);
Serial.print(" ");
Serial.println(yaxis);
double x = (double)xaxis; // convert to double for matrix calcs
double y = (double)yaxis; // convert to double for matrix calcs
Serial.println("x and y values after conversion are");
Serial.print(x);
Serial.print(" ");
Serial.println(y);
x = x - 100; // removing the 100 added for data transfer
y = y - 100; // removing the 100 added for data transfer
Serial.println("x and y - 100 values are");
Serial.print(x);
Serial.print(" ");
Serial.println(y);
BLA::Matrix<3,1> dirMatrix = {x, y, 0}; // generate matrix with values of x and y
BLA::Matrix<3,1> motorMatrix = wheelMatrix*dirMatrix; // multiply matrix
motor1Matrix = motorMatrix(0); // set matrix output for motor 1
motor2Matrix = motorMatrix(1); // set matrix output for motor 2
motor3Matrix = motorMatrix(2); // set matrix output for motor 3
if (motor1Matrix >= 0) { // if the value is greater than or equal to 0 i.e not negative
digitalWrite(9, HIGH);
Serial.println("motor 1 is high");
}
else {
digitalWrite(9, LOW);
Serial.println("motor 1 is low");
}
if (motor2Matrix >= 0) { // if the value is greater than or equal to 0 i.e not negative
digitalWrite(3, HIGH);
Serial.println("motor 2 is high");
}
else {
digitalWrite(3, LOW);
Serial.println("motor 2 is low");
}
if (motor3Matrix >= 0) { // if the value is greater than or equal to 0 i.e not negative
digitalWrite(6, HIGH);
Serial.println("motor 3 is high");
}
else {
digitalWrite(6, LOW);
Serial.println("motor 3 is low");
}
motor1PWM = map(motor1Matrix, -100, 100, 255, 0);
motor2PWM = map(motor2Matrix, -100, 100, 255, 0);
motor3PWM = map(motor3Matrix, -100, 100, 255, 0);
Serial.print("motor 1 speed is ");
Serial.println(motor1PWM);
Serial.print("motor 2 speed is ");
Serial.println(motor2PWM);
Serial.print("motor 3 speed is ");
Serial.println(motor3PWM);
analogWrite(10, motor1PWM);
analogWrite(4, motor2PWM);
analogWrite(5, motor3PWM);
}
void setup() {
Serial.begin(9600); // open serial connection
BLE.begin(); // begin BLE device
BLE.setLocalName("Wheel"); // set local name to "Wheel"
BLE.setAdvertisedService(wheel); // set advertised service to the "wheel" service
wheel.addCharacteristic(wheelx); // add thw two characteristics to the wheel service
wheel.addCharacteristic(wheely);
BLE.addService(wheel); // add service
wheelx.writeValue(0x00); // set characteristic values to 0
wheely.writeValue(0x00);
BLE.advertise(); // begin advertising the wheel service with two characteristics
// set up pinmodes
pinMode(9, OUTPUT); // Motor 1 Direction
pinMode(10, OUTPUT); // Motor 1 PWM
pinMode(3, OUTPUT); // Motor 2 direction
pinMode(4, OUTPUT); // Motor 2 pwm
pinMode(6, OUTPUT); // Motor 3 direction
pinMode(5, OUTPUT); // Motor 3 pwm
}
void loop() {
BLEDevice controller = BLE.central(); // assign a device controller to the central node connecting
if (controller){ // if controller is connected
Serial.println("controller connected");
while (controller.connected()) { // while the controller is connected
Serial.println("reading controller values");
wheelx.readValue(Ax); // assign the value from the wheelx characteristic to Ax
wheely.readValue(Ay); // assign the value from the wheely characteristic to Ay
Serial.println("starting motor control function");
motorControl(Ax, Ay); // run the motor control function
}
Serial.println("Controller disconnected");
}
}