Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use servo.write instead of analogWrite #8

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 27 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,32 @@
# nRF24-Esk8-Remote

Control your electric skateboard an Arduino controlled remote. This repository contains the needed software for the remote and the receiver, however you will need to install a few Arduino Libraries in order to compile the Arduino sketches. The Arduino IDE comes with most of the needed libraries, but you will ned to manually install VescUartControl from RollingGecko: https://github.com/RollingGecko/VescUartControl.
After building and hacking several together, I ended up with this design of my own based on electronics and software from SolidGeek (available at https://github.com/SolidGeek/nRF24-Esk8-Remote).

The remote I designed has the following features:

You can find the 3D-models for the remote (STL files) on Thingiverse: https://www.thingiverse.com/thing:2454391 and read more about the project on: https://www.electric-skateboard.builders/t/simple-3d-printed-nrf-remote-arduino-controlled/28543
- A dead man's switch which deactivates the throttle when the remote is not held (safety feature because the trigger can accidentally go off otherwise, ask me how I know)
- A mode switch which swaps between displayed data (Speed, distance, battery voltage, Ah drawn, current draw)
- Ergonomic OLED display position so you don't need to twist your wrist to read it.
- Menu to adjust settings
- Programmable deck selection via menu
- Calibration of throttle via menu
- Ambidextrous design, swap to left hand use by adjusting the script-
- Skate bearing used in trigger mechanism for smoother operation as well just a fun detail considering it's meant for an esk8
- Hall sensor instead of potentiometer to prevent potential wear of a pot

I have made a Wiki here on Github, with a few tips and guides on how to build the remote. The Wiki can be found here: https://github.com/SolidGeek/nRF24-Esk8-Remote/wiki
STLs available at https://www.thingiverse.com/thing:2800544

Donation link: https://www.paypal.me/solidgeek
Youtube video available at https://www.youtube.com/watch?v=gQl7mLMAiAs&feature=youtu.be

Part List available at https://docs.google.com/spreadsheets/d/1vXR9ce0m25Ap6XxzlymFo_pfpIeT2RAqWCypW-a-Jes/edit?usp=sharing

PCB Files available at https://easyeda.com/ervinelin/New_Project-35f7bf3537744cda8e1064904f6a78a5

Forum discussion available at https://www.electric-skateboard.builders/t/diy-trigger-style-remote-with-telemetry-complete-guide/48231

Build guide available at https://github.com/ModMiniMan/nRF24-Esk8-Remote/wiki

You will need to have intermediate soldering skills to complete the build as well as knowledge on how to program an Arduino and adjust simple code. Of course if you print this yourself you will need to know how to 3D print.

Caveats:
Remote is experimental and not an off the shelf product that has undergone proper testing. Build and use at your own risk. Please bench test extensively before actual use. Lastly, I highly recommend protective gear when using the remote just in case something doesn't work (many many things can go wrong)
Binary file added images/CopperTape.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/DIY-Remote-PCB-Bottom.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/DIY-Remote-PCB-Top.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/DIY_Kit_1.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/DIY_Kit_2.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/DIY_Remote_Massing.JPG
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/Deck_Select.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/Hacked_MiniRemote_1.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/Hacked_MiniRemote_2.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/HallSensor.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/InitialSketch.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/LC_Filter.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/NRF_MainPCB.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/NRF_SolderedPins.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/OLED_SwapDirection.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/OLED_Wiring_1.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/OLED_Wiring_2.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/PCB_1.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/PCB_2.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/PCB_3.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/PCB_4.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/PCB_Build.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/PCB_Soldered.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/PCBs.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/PaperPrint.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/RemoteCasingPrint.jpg
Binary file added images/RemoteCasingPrint_2.jpg
Binary file added images/Remote_Casing.jpg
Binary file added images/Rx_1.jpg
Binary file added images/Rx_2.jpg
Binary file added images/Rx_HeatShrink.jpg
Binary file added images/Rx_NRF.jpg
Binary file added images/Rx_OLD.jpg
Binary file added images/Rx_PCB_OLD.png
Binary file added images/Rx_inBag.jpg
Binary file added images/Schematic.jpg
Binary file added images/Sketches.jpg
Binary file added images/SwitchWiring.jpg
Binary file added images/Transmitter_1.jpg
Binary file added images/Transmitter_2.jpg
Binary file added images/Transmitter_DM_Switch.jpg
Binary file added images/Transmitter_Internals_1.jpg
Binary file added images/Transmitter_Internals_2.jpg
Binary file added images/TriggerMech_OLD.jpg
Binary file added images/USB_PortAlign.jpg
Binary file removed images/electronics_image_tp4056.png
Diff not rendered.
Binary file removed images/electronics_schematic_part1.png
Diff not rendered.
Binary file removed images/electronics_schematic_part2.png
Diff not rendered.
Binary file removed images/image_remote.jpg
Diff not rendered.
1 change: 0 additions & 1 deletion images/images.txt

This file was deleted.

Binary file removed images/remote_3dprint.png
Diff not rendered.
93 changes: 0 additions & 93 deletions receiver/receiver.ino

This file was deleted.

150 changes: 150 additions & 0 deletions receiver_VESC6/receiver_VESC6.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
#include <SPI.h>
#include <nRF24L01.h>
#include "RF24.h"
#include "VescUart.h"
#include <Servo.h>
Servo myservo;

//#define DEBUG

#ifdef DEBUG
#define DEBUG_PRINT(x) Serial.println (x)
#include "printf.h"
#else
#define DEBUG_PRINT(x)
#endif

#define SERIALIO Serial

struct vescValues {
float ampHours;
float inpVoltage;
long rpm;
long tachometerAbs;
float avgMotorCurrent;
};

RF24 radio(9, 10);
//int radioChannel = 108; // Above most WiFi frequencies
const uint64_t pipe = 0xA8A8FEFEE1LL; // Please change this to your own pipe address
const uint8_t defaultChannel = 108;
uint32_t timeoutTimer = 0;

// Last time data was pulled from VESC
unsigned long lastUartPull;

// Defining struct to handle callback data (auto ack)
struct callback {
float ampHours;
float inpVoltage;
long rpm;
long tachometerAbs;
float avgMotorCurrent;
};

struct bldcMeasure uartData;
struct callback returnData;

bool recievedData = false;
uint32_t lastTimeReceived = 0;

int motorSpeed = 1500 ; // This is in microseconds
int timeoutMax = 500;
int throttlePin = 5;
//int resetTrigger = 0;

struct bldcMeasure measuredValues;

struct vescValues data;
unsigned long lastDataCheck;

void setup() {

SetSerialPort(&SERIALIO);
SERIALIO.begin(115200);

myservo.attach(throttlePin);
myservo.write(motorSpeed);
//pinMode(throttlePin, OUTPUT); // This is the old analogWrite method
//analogWrite(throttlePin, motorSpeed); // This is the old analogWrite method

initiateReceiver();
}

void loop() {

getVescData();

// If transmission is available
while (radio.available())
{
// The next time a transmission is received on pipe, the data in gotByte will be sent back in the acknowledgement (this could later be changed to data from VESC!)
radio.writeAckPayload(pipe, &data, sizeof(data));

// Read the actual message
radio.read(&motorSpeed, sizeof(motorSpeed));
recievedData = true;
}

if (recievedData == true)
{
// A speed is received from the transmitter (remote).

lastTimeReceived = millis();
recievedData = false;

// Write the PWM signal to the ESC (0-255) // This is the old analogWrite method
//analogWrite(throttlePin, motorSpeed); // This is the old analogWrite method
// Maps motorspeed signal from remote from 0-255 to 1000-2000ms
motorSpeed = map(motorSpeed, 0, 255, 1000, 2000);
// Writes microseconds to throttle pin
myservo.writeMicroseconds(motorSpeed);

}
else if ((millis() - lastTimeReceived) > timeoutMax)
{
// No speed is received within the timeout limit.
//analogWrite(throttlePin, motorSpeed);
myservo.writeMicroseconds(1500);
}
}

void initiateReceiver() {

// Start radio communication
radio.begin();
// radio.setChannel(defaultChannel);
radio.setDataRate(RF24_250KBPS);
//radio.setChannel(108);
radio.enableAckPayload();
radio.enableDynamicPayloads();
radio.openReadingPipe(1, pipe);
radio.startListening();

}

void getVescData() {

if (millis() - lastDataCheck >= 250) {

lastDataCheck = millis();

// Only transmit what we need
if ( VescUartGetValue(uartData) )
{
data.ampHours = uartData.ampHours;
data.inpVoltage = uartData.inpVoltage;
data.rpm = uartData.rpm;
data.tachometerAbs = uartData.tachometerAbs;
data.avgMotorCurrent = uartData.avgMotorCurrent;
}
else
{
data.ampHours = 0.0;
data.inpVoltage = 0.0;
data.rpm = 0;
data.tachometerAbs = 0;
data.avgMotorCurrent = 0;
}
}
}