Everything that I put after the initialization does work, except for the writemicroseconds.
So I can see the input of the XBOX controller (for example when moving the sticks), and can see the value of ms_min change.
However, it seems that it does not give this ms_min as input to the servo.
When I remove the initialization, I can give the ms_min as input to the servo (for example a static value or sinusoidal signal).
#include <Servo.h>
#include <XBOXRECV.h>
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
// Control servo variables
Servo myservo;
const int ms_min = 1000; // minimum [ms] sent to servo
const int ms_max = 2100; // maximum [ms] sent to servo
// Timing constants
unsigned long NewTick; // [ms] time start of current loop
unsigned long LastTick; // [ms] time start of previous loop
float dt; // [ms] time between consecutive loops
float interval_constant = 20; // [ms] per signal send
int count_setup = 20; // [s] setup time
// Servo constants
int ms_input = ms_min;
// Xbox controller variables
int Hat_tol = 5000; // Tolerance on when the Xbox controller responds to input LeftHatY
float throttle_analog; // Value received from input LeftHatY
float throttle; // 0-1, gives rate of minimum to maximum input LeftHatY
int k = 0; // Variable to trigger 'Controller connected' message.
USB Usb;
XBOXRECV Xbox(&Usb);
float ms_float = (float) ms_min; // [ms] calculated from Xbox Controller input (float)
int ms_int = ms_min; // [ms] calculated from Xbox Controller input (integer)
void setup() {
Serial.begin(9600);
while (!Serial); // Wait for serial port to connect
// Give user time to connect ESC to Arduino board
Serial.print("\n\n Program started, connect ESC to motor ("); Serial.print(count_setup); Serial.println(" seconds)");
for (uint8_t ii = count_setup; ii > 0; ii--) {
Serial.print(ii); Serial.println(". "); delay(1000);
}
// ESC calibration and attach Servo to pin 9
Serial.println("ESC calibration started");
myservo.attach(9);
esc();
Serial.println("ESC calibration completed");
Serial.println(" ");
// USB initialization
Serial.println("Start USB Init");
Serial.println(" ");
if (Usb.Init() == -1) {
Serial.print(F("\r\nOSC did not start"));
while (1);
}
Serial.println("USB Init complete");
Serial.println("Connect controller (3 seconds)");
delay(3000);
}
void esc()
{
delay(5000);
Serial.println("Sending lowest throttle ms_min");
myservo.writeMicroseconds(ms_min);
delay(2000);
Serial.println("Low throttle sent");
}
void loop() {
NewTick = millis();
dt = NewTick - LastTick;
if (dt > 50) {
ms_input = Define_input(); //Retrieve input servo from XboxController
myservo.writeMicroseconds(ms_input); //Send input to servo
LastTick = NewTick;
}
// Output to Serial to see values
Serial.print(NewTick);
Serial.print(",");
Serial.print(ms_input);
Serial.println("");
}
// Check input of Xbox controller
int Define_input()
{
throttle = 0; //Set throttle to 0, so that if no input is found, no throttle (ms_min) is sent
Usb.Task(); //Polls connected usb devices for updates to their status
if (Xbox.XboxReceiverConnected) {
if (Xbox.Xbox360Connected[0]) {
if (k==0){ //Print to Serial whenever the controller is connected
Serial.println("Controller connected!");
k = 1;
}
if (Xbox.getAnalogHat(LeftHatY, 0) > Hat_tol) { //If value of LeftHatY is larger than tolerance 'Hat_tol'
throttle_analog = Xbox.getAnalogHat(LeftHatY, 0);
throttle = (throttle_analog - Hat_tol) / (32767 - Hat_tol); // Calculate the throttle (0 - 1)
}
}
}
ms_float = ms_min+(ms_max-ms_min)*throttle; // Calculate the input servo [ms] from throttle.
ms_int = (int) ms_float; //Convert input servo from float to integer
return ms_int;
}
I have a theory on this, but I do not have the resources available to test it. Would you mind testing with a few minor adjustments to your code?
#include <Servo.h>
#include <XBOXRECV.h>
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
// Control servo variables
Servo myservo;
const int ms_min = 1000; // minimum [ms] sent to servo
const int ms_max = 2100; // maximum [ms] sent to servo
// Timing constants
unsigned long NewTick; // [ms] time start of current loop
unsigned long LastTick; // [ms] time start of previous loop
float dt; // [ms] time between consecutive loops
float interval_constant = 20; // [ms] per signal send
int count_setup = 20; // [s] setup time
// Servo constants
int ms_input = ms_min;
// Xbox controller variables
int Hat_tol = 5000; // Tolerance on when the Xbox controller responds to input LeftHatY
float throttle_analog; // Value received from input LeftHatY
float throttle; // 0-1, gives rate of minimum to maximum input LeftHatY
int k = 0; // Variable to trigger 'Controller connected' message.
USB Usb;
XBOXRECV Xbox(&Usb);
float ms_float = (float) ms_min; // [ms] calculated from Xbox Controller input (float)
int ms_int = ms_min; // [ms] calculated from Xbox Controller input (integer)
void setup() {
Serial.begin(9600);
while (!Serial); // Wait for serial port to connect
// Give user time to connect ESC to Arduino board
Serial.print("\n\n Program started, connect ESC to motor ("); Serial.print(count_setup); Serial.println(" seconds)");
for (uint8_t ii = count_setup; ii > 0; ii--) {
Serial.print(ii); Serial.println(". "); delay(1000);
}
// ESC calibration and attach Servo to pin 9
Serial.println("ESC calibration started");
//myservo.attach(9);
esc();
Serial.println("ESC calibration completed");
Serial.println(" ");
// USB initialization
Serial.println("Start USB Init");
Serial.println(" ");
if (Usb.Init() == -1) {
Serial.print(F("\r\nOSC did not start"));
while (1);
}
Serial.println("USB Init complete");
Serial.println("Connect controller (3 seconds)");
delay(3000);
}
void esc()
{
delay(5000);
Serial.println("Sending lowest throttle ms_min");
myservo.writeMicroseconds(ms_min);
delay(2000);
Serial.println("Low throttle sent");
}
void loop() {
NewTick = millis();
dt = NewTick - LastTick;
if (dt > 50) {
ms_input = Define_input(); //Retrieve input servo from XboxController
//myservo.writeMicroseconds(ms_input); //Send input to servo
digitalWrite(9,HIGH);
delay(ms_input);
digitalWrite(9,LOW);
LastTick = NewTick;
}
// Output to Serial to see values
Serial.print(NewTick);
Serial.print(",");
Serial.print(ms_input);
Serial.println("");
}
// Check input of Xbox controller
int Define_input()
{
throttle = 0; //Set throttle to 0, so that if no input is found, no throttle (ms_min) is sent
Usb.Task(); //Polls connected usb devices for updates to their status
if (Xbox.XboxReceiverConnected) {
if (Xbox.Xbox360Connected[0]) {
if (k==0){ //Print to Serial whenever the controller is connected
Serial.println("Controller connected!");
k = 1;
}
if (Xbox.getAnalogHat(LeftHatY, 0) > Hat_tol) { //If value of LeftHatY is larger than tolerance 'Hat_tol'
throttle_analog = Xbox.getAnalogHat(LeftHatY, 0);
throttle = (throttle_analog - Hat_tol) / (32767 - Hat_tol); // Calculate the throttle (0 - 1)
}
}
}
ms_float = ms_min+(ms_max-ms_min)*throttle; // Calculate the input servo [ms] from throttle.
ms_int = (int) ms_float; //Convert input servo from float to integer
return ms_int;
}
Are you continuously getting the "did not start" message?.
What i did witht the chqnge of code above (and i missed the void esc() part, my appologies) was attempt to eliminate use of servo.write or servi.writeMicroseconds. My goal in this was to determine if the USB library (which XBOXRECV.h is part of) is killing interrupts which would make servo library functions unuseable. If you wanted to try again you could modify void esc() to operate the same way as the changes I made in loop (sorry typing from phone so can't really paste code).
#include <Servo.h>
#include <XBOXRECV.h>
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
// Control servo variables
Servo myservo;
const int ms_min = 1000; // minimum [ms] sent to servo
const int ms_max = 2100; // maximum [ms] sent to servo
// Timing constants
unsigned long NewTick; // [ms] time start of current loop
unsigned long LastTick; // [ms] time start of previous loop
float dt; // [ms] time between consecutive loops
float interval_constant = 20; // [ms] per signal send
int count_setup = 20; // [s] setup time
// Servo constants
int ms_input = ms_min;
// Xbox controller variables
int Hat_tol = 5000; // Tolerance on when the Xbox controller responds to input LeftHatY
float throttle_analog; // Value received from input LeftHatY
float throttle; // 0-1, gives rate of minimum to maximum input LeftHatY
int k = 0; // Variable to trigger 'Controller connected' message.
USB Usb;
XBOXRECV Xbox(&Usb);
float ms_float = (float) ms_min; // [ms] calculated from Xbox Controller input (float)
int ms_int = ms_min; // [ms] calculated from Xbox Controller input (integer)
void setup() {
Serial.begin(9600);
while (!Serial); // Wait for serial port to connect
// Give user time to connect ESC to Arduino board
Serial.print("\n\n Program started, connect ESC to motor ("); Serial.print(count_setup); Serial.println(" seconds)");
for (uint8_t ii = count_setup; ii > 0; ii--) {
Serial.print(ii); Serial.println(". "); delay(1000);
}
// ESC calibration and attach Servo to pin 9
Serial.println("ESC calibration started");
//myservo.attach(9);
esc();
Serial.println("ESC calibration completed");
Serial.println(" ");
// USB initialization
Serial.println("Start USB Init");
Serial.println(" ");
if (Usb.Init() == -1) {
Serial.print(F("\r\nOSC did not start"));
while (1);
}
Serial.println("USB Init complete");
Serial.println("Connect controller (3 seconds)");
delay(3000);
}
void loop() {
NewTick = millis();
dt = NewTick - LastTick;
if (dt > 50) {
ms_input = Define_input(); //Retrieve input servo from XboxController
//myservo.writeMicroseconds(ms_input); //Send input to servo
digitalWrite(9,HIGH);
delayMicroseconds(ms_input);
digitalWrite(9,LOW);
LastTick = NewTick;
}
// Output to Serial to see values
Serial.print(NewTick);
Serial.print(",");
Serial.print(ms_input);
Serial.println("");
}
// Check input of Xbox controller
int Define_input()
{
throttle = 0; //Set throttle to 0, so that if no input is found, no throttle (ms_min) is sent
Usb.Task(); //Polls connected usb devices for updates to their status
if (Xbox.XboxReceiverConnected) {
if (Xbox.Xbox360Connected[0]) {
if (k==0){ //Print to Serial whenever the controller is connected
Serial.println("Controller connected!");
k = 1;
}
if (Xbox.getAnalogHat(LeftHatY, 0) > Hat_tol) { //If value of LeftHatY is larger than tolerance 'Hat_tol'
throttle_analog = Xbox.getAnalogHat(LeftHatY, 0);
throttle = (throttle_analog - Hat_tol) / (32767 - Hat_tol); // Calculate the throttle (0 - 1)
}
}
}
ms_float = ms_min+(ms_max-ms_min)*throttle; // Calculate the input servo [ms] from throttle.
ms_int = (int) ms_float; //Convert input servo from float to integer
return ms_int;
}
void esc()
{
delay(5000);
Serial.println("Sending lowest throttle ms_min");
//myservo.writeMicroseconds(ms_min);
for (int calibrationCount = 0; calibrationCount < 150; calibrationCount++)
{
digitalWrite(9, HIGH);
delayMicroseconds(1000);
digitalWrite(9, LOW);
delayMicroseconds(19000);
}
Serial.println("Low throttle sent");
}
I changed esc() so it will loop for roughly 3 seconds while sending 1ms pulse (1000 microseconds). How long it actually needs to be held low throttle depends on your particular ESC, but I think 3 seconds should be long enough to get most ESCs to arm, if you need to change the time it takes to arm just change "calibrationCount < 150" in esc(), the way I figure this is it should loop 50ish times per second (servo specification is roughly 1-2ms high pulse total frame width of 20ms, so 50hz, so 150 loops equals 3 seconds).
Also I changed the delay(ms_input) in loop to delayMicroseconds(ms_input), it should have been that way in the first place, my head just was not attached correctly that day it would appear.