// this code was adapted from Drew Dibble original code to run on arduino due
//you´ll need a library called "soft_uart.h" ,elapsedmillis.h ,liquidcrystal.h ,and bignumbers.h installed ,search the web for it.
// this code uses the arduino due to talk to the main board Hoverboard using a 3.2v hall thumb throtlle
//instead of the gyro board.
// odometer version is from Angel Garcia de la Cruz and bignumber lcd from Sean Auffinger
// version 1.0 by Alvaro Fogassa on 23/05/2022
// !!! CAUTION !!! , do not attempt to load the sketch to arduino with the hoverboard turned on or it might damage your pc.
// the usb is not isolated and will burn your pc. make a guess how i´ve found that out.
///// 9bit serial ///////////////////////////////////////
#include "soft_uart.h"
using namespace soft_uart;
using namespace soft_uart::arduino_due;
#define RX_PIN 10 // software serial port's reception pin azul
#define TX_PIN 11 // software serial port's transmision pin verde
#define SOFT_UART_BIT_RATE 26315
#define RX_BUF_LENGTH 256 // software serial port's reception buffer length
#define TX_BUF_LENGTH 256 // software serial port's transmision buffer length
uint32_t counter1=256;
uint32_t counter2=1;
uint32_t counter3=85;
uint32_t counter4=0xFF;
int sensorValue = 0; // value read from the pot
int outputValue = 0; // value output to the PWM (analog out)
const int analogInPin = A0; // Analog input pin that the potentiometer is attached to
// declaration of software serial port object serial_tc4
// which uses timer/counter channel TC4
serial_tc4_declaration(RX_BUF_LENGTH,TX_BUF_LENGTH);
//serial_tc1_declaration(RX_BUF_LENGTH,TX_BUF_LENGTH);
auto& serial_obj=serial_tc4; //
// serial_tc4_t& serial_obj=serial_tc4;
//////////////// lcd update every 100ms //////////////////////////////////////////////
#include <elapsedMillis.h>
elapsedMillis timeElapsed; //declare global if you don't want it reset every time loop runs
unsigned int interval = 100;
///////////////// lcd bignumbers //////////////////////////////////////////////
#include <LiquidCrystal.h>
#include <BigNumbers.h>
const int lcdD7Pin = 52; // LCD D7 pin 14
const int lcdD6Pin = 50; // LCD D6 pin 13
const int lcdD5Pin = 48; // LCD D5 pin 12
const int lcdD4Pin = 46; // LCD D4 pin 11
const int lcdEPin = 44; // LCD E Pin 6
const int lcdRSPin = 42; // LCD RS pin 4
LiquidCrystal lcd(lcdRSPin, lcdEPin, lcdD4Pin, lcdD5Pin, lcdD6Pin, lcdD7Pin); // construct LCD object
BigNumbers bigNum(&lcd); //construct BigNumbers object, passing to it the name of our LCD object
// Circumference of bicycle wheel in meters.
float bicycleWheelCircumference = 2.104867;
const int revolutionButton = 2;
boolean lastRevolutionButton = LOW;
boolean currentRevolutionButton = LOW;
unsigned long lastRevolutionStartTime = 0;
unsigned long revolutionTime = 0; // This must be the biggest display mode number
const int currentDisplayMode = 3;
float currentDistanceK;
int currentMaximumKPH;
int currentAverageKPH;
int currentKPH;
float currentDistanceM;
int currentMaximumMPH;
int currentAverageMPH;
int currentMPH;
unsigned long revolutionCount = 0;
unsigned long currentTime = 0;
unsigned long currentMovingTime = 0;
unsigned long lastStoppedTime = 0;
unsigned long stoppedTime = 0;
boolean tooSlow = LOW;
float stoped=0.00; // added to display zero when stoped
float km = 0.00;
float kph = 0.00;
int intHours;
int intMinutes;
int intSeconds;
long previousMillis = 0; // will store last time Lcd was updated
unsigned long milliSecondsInSecond = 1000;
unsigned long milliSecondsInMinute = 60000;
unsigned long milliSecondsInHour = 3600000;
void setup()
{
// serial_obj initialization
serial_obj.begin(
RX_PIN,
TX_PIN,
SOFT_UART_BIT_RATE,
soft_uart::data_bit_codes::NINE_BITS,
soft_uart::parity_codes::NO_PARITY,
soft_uart::stop_bit_codes::ONE_STOP_BIT
);
pinMode(revolutionButton, INPUT_PULLUP); // Sets the hall switch to be an input
lcd.begin(16,2); // setup LCD rows and columns
bigNum.begin(); // set up BigNumbers
lcd.clear(); // clear display
}
int sp=0;
void loop()
{
//////////////////motor controll /////////////////////////////////////////
//we measure 50 times adn make the mean average the acelerator hall sensor value
long measure = 0;
for(int i = 0; i < 50; i++){
int value = measure += analogRead(analogInPin);
}
measure /= 50;
// read the analog in mean value and map it to outputvalue:
outputValue = map(measure, 477, 630, -1500, 0); // maps the throttle to the output values,need to be calibrated.
sp=outputValue; // makes the motor to turn only forward.
if (sp>=1)
{ sp=0; }
serial_obj.write(counter1)%(1<<static_cast<int>(soft_uart::data_bit_codes::NINE_BITS));
serial_obj.write(sp&counter4)%(1<<static_cast<int>(soft_uart::data_bit_codes::NINE_BITS));
serial_obj.write((sp >> 8) & counter4)%(1<<static_cast<int>(soft_uart::data_bit_codes::NINE_BITS));
serial_obj.write( sp & counter4)%(1<<static_cast<int>(soft_uart::data_bit_codes::NINE_BITS));
serial_obj.write((sp >> 8) & counter4)%(1<<static_cast<int>(soft_uart::data_bit_codes::NINE_BITS));
serial_obj.write(counter3)%(1<<static_cast<int>(soft_uart::data_bit_codes::NINE_BITS));
delayMicroseconds(200);
//////////////// odometro //////////////////////////////////////////
// Get current millis
currentTime = millis();
if (tooSlow == HIGH) {
if ((currentTime - lastStoppedTime) >= 1000)
{
stoppedTime = stoppedTime + 1000;
lastStoppedTime = currentTime;
}
}
// read Hall sensor
currentRevolutionButton = debounce(lastRevolutionButton, revolutionButton);
//currentRevolutionButton = (lastRevolutionButton, revolutionButton);
if (lastRevolutionButton == HIGH && currentRevolutionButton == LOW)
{ // Increase wheel revolution count
revolutionCount++;
// Compute millis it took for this latest revolution
if (lastRevolutionStartTime > 0)
{
revolutionTime = currentTime - lastRevolutionStartTime;
kph = (3600000 / revolutionTime) * bicycleWheelCircumference / 1000;//
currentKPH = kph;
// currentMPH = currentKPH * 0.62137119;
if (currentMaximumKPH < currentKPH) // If current speed is new maximum speed for this lap then store it
{
currentMaximumKPH = currentKPH;
//currentMaximumMPH = currentMaximumKPH * 0.62137119;
}
}
lastRevolutionStartTime = currentTime;
}
lastRevolutionButton = currentRevolutionButton;
// Determine if wheel revolution has taken too long. If so, cyclist has stopped display "--" instead of current speed.
if ((currentTime - lastRevolutionStartTime) >= 5000)
{ tooSlow = HIGH; }
if ((currentTime - lastRevolutionStartTime) < 5000)
{ tooSlow = LOW;}
if (revolutionCount > 0) { // Calculate current distance
currentDistanceK = revolutionCount * (bicycleWheelCircumference / 1000);
// currentDistanceM = currentDistanceK * 0.62137119;
currentMovingTime = currentTime - stoppedTime;
// Calculate average speed
currentAverageKPH = currentDistanceK * 3600000 / currentMovingTime;//em millis
// currentAverageMPH = currentAverageKPH * 0.62137119;
}
// Display information on LCD
if (timeElapsed > interval)
{
lcd.setCursor(8,0);
lcd.print(currentDistanceK);
lcd.print(" km");
if (tooSlow == LOW)
{
bigNum.displayLargeInt(currentKPH , 0, 2, false);
}
else if (tooSlow == HIGH){
bigNum.displayLargeInt(stoped, 0, 2, false);
}
// Display Average KPH in bottom right
lcd.setCursor(8, 1);
lcd.print("avg");
lcd.setCursor(12, 1);
if (currentAverageKPH < 10)
{
lcd.print(" ");
}
lcd.print(currentAverageKPH);
timeElapsed = 0; // reset the counter to 0 so the counting starts over.
}
}
/////////////// loop end ////////////////////////////
//A debouncing function that can be used for any button
boolean debounce(boolean last, int pin) {
boolean current = digitalRead(pin);
if (last != current)
{ delay(1);
current = digitalRead(pin);
}
return current;
}
Friday, August 12, 2022
The code
Subscribe to:
Post Comments (Atom)
The code
// this code was adapted from Drew Dibble original code to run on arduino due //you´ll need a library called "soft_uart.h" ,elap...
No comments:
Post a Comment