Rotellino

by a-beltrando-1821 in Workshop > Energy

81 Views, 1 Favorites, 0 Comments

Rotellino

Cattura.PNGasdfesdfdgffhdgfhstdgfg.PNG

Rotellino is a DIY bike light.

Rotellino works using the variation of the magnetic field, generated by the movement of the bike wheel rim, to rotate a rotor made up of 6 magnets and generate electricity.

Once working, the goal is to monitor the voltage and electricity data arriving from the sensors mounted on the rotellino  with an app (blynk)  on a mobile phone

Supplies

OIP.jpg
round-n52-silver-magnets-6x3mm.jpg
R.jpg
download.jpg
OIP.jpg


  • 2 plastic bearings 623 3x10x4mm 
  • 6  N52 magnets 6x3 mm 
  • 2 M3 20 mm screws + nuts 
  • 2 x 5mm bright white LEDs
  • Voltage and electricity sensors
  • phone and google sheets for data monitoring
  • 3d printer
  • Drill 
  • Copper wire


OIP.jpg

 build a coil by wrapping around a support the copper wire


attach the leds to the coil



design the rotellino’s body and supports on a 3d software

 3d print the component designed

assemble the rotor, made out of six magnets  that are placed alternating their polarity

 assemble all the parts together

 write the arduino code to make the voltage and electricity sensors work and to send the data they collect to a google sheets file

36f43c9f-1bb8-4875-8db8-3404be6a16ac.jpg
871a4a11-15fe-4e10-ab53-7a655ce198a2.jpg

test the functioning and of the rotellino with an oscilloscope 

asdad.PNG

create a google sheets file to collect and analize the data took from the rotellino

asdad.PNG

connect arduino with google sheets

asdad.png

monitor from remote the data coming from the rotellino

Video of the Rotellino Working

Google Sheets Link:

asdad.PNG

https://docs.google.com/spreadsheets/d/1g_iSECpZtVPYQIcYqwiuH6AiCyx23LEwCrdgco5Elpg/edit#gid=0

Arduino Code

th.jpg

#include <Arduino.h>

#include <WiFi.h>

#include <WiFiManager.h>

#include <Adafruit_Sensor.h>

#include <time.h>

#include <ESP_Google_Sheet_Client.h>


//For ACS712 current sensor

const int sensorIn = 4;

int mVperAmp = 185;           // this the 5A version of the ACS712 -use 100 for 20A Module and 66 for 30A Module

float Voltage, VRMS, AmpsRMS;


//For Hall effect sensor

int hall_pin = 17;

float hall_thresh = 5.0;

float rpm_val, time_passed;


//For Wi-fi connection

unsigned long previousMillis = 0;

unsigned long interval = 30000;


// Google Project ID

#define PROJECT_ID "iot-rotellino"


// Service Account's client email

#define CLIENT_EMAIL "iot-rotellino@iot-rotellino.iam.gserviceaccount.com"


// Service Account's private key

const char PRIVATE_KEY[] PROGMEM = "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDRU3XmSDL8oaiE\nOOu0YUdlCcqMf2UAPj0yh0roocl6VIp/bX+qKD3MHV9fOfHfxTMlcvsEGPtMDR2J\n3Kn7z2DX0s9t5D85qL3yq0FtlZarhrkt/EVFtSGyQ4brbVfRfX3z8XpTSzoA8S7L\nh++wW79ylEl+GlBP7taeSOtXDUOfEorXsu2mOv1pL7L5VJdWcGofwJJuWpjLFnWW\ndhxwPMxchRsCIAQs7ujSuoCkPVDZXXMqTE0OgbZv9qzuZ93uWn47lhuItL5XkO7D\nOFTK/vc1M6MvuXKf7riwxUp96iFcP1M7C6tsgVBoAMRr+sFTCUp+eDvkpV2vnGXO\nck5RkoBxAgMBAAECggEAB2jCzkxDmGphjFbLqlrjWf5A5UrEan/0JAaNXIErSuTq\nKrzXh+zVfyMgkz6WijBp4v0REH5X4BjeFIP6SlCFU4OsVgphszHwrexpVry0sPd3\n34VuWg093kL0LzhXMZWVfsh52QU+6qCe1HbksxUwuhh3tNAE2WPmqBESkv8uzmVF\n65rDIW5xdbe4Nt31QyhBo3FLomvGSIq6RtcTDiJGB/jtkRP3Ugs7P1Ps0wlpTcux\ngWAzNjDIkpy4dzpXsFK02qCI8QibFQia67C967EQPGJmoTUIwLQPZKaHan1d7Dpe\neAoEol+8jI859piPsE4/ZuvxseYFuo3Sa0xcxwAhdwKBgQD37QvDMZEIR5V6uSJY\nIWIWS9w2il28T+zqS8cBqVVRrJD2AL1VLAuFLMgw4vGw0MFAjufeystmpWSNSzN3\nA/awCnAyq9tivDZZTJALsIM+3llXJwxgYhAtlkGwwE72eQnJmEFGmmYqvYKbExL6\nfDvbI00GtFsDTtc7aCXa5ro09wKBgQDYJJuL0bZMiqZMlwqSOHZ15nbIhsUPEFDr\nRW8T7I4h4IvgXK9LqWfGRWg5fdDssPScPI2+eFdZpjGgEb5JAjhqSYsYIAokRw5x\nHF9oBfbuOWo6E5bso3fpeSYHKirO5MVfrehUrW0e+Z0Ylhoyg5/CuBUsHq7IgDK/\nfHY4Gk/j1wKBgHpjKktRTKcpr0DF445d7G3VRQAnjd5IFkwS3EqVrOiEp4rJEq3Y\n8FbtpGV9opIGe1/DK/NvaLljLCAT33QBIOYGQRzCeapj/vBWO0WJ/UArwy6iuBlc\nT2AxrHv0cwZ4+bvqzU5tKcIviynCYLwGWAX1hzCoF8WqRdWttAI7o/BBAoGAKWPp\nPX8tT78FVYlfBt01IiK+AGx+dAIF3Ofw+3nDRg1/+7kEAJMyQi+sY8YKKilAzmJy\nKlVVNN+0hRigvc5lC0WGE1qfVo8c3uA2DO+Hd9sa0oBJ2Ir9PYJrm9ehVvlMKqRc\n50pGqTXXtYuY/K9j+p/Rvh8qDU8vaKfm45t2TQUCgYEAwxL3f2g9V2tdyIQXN/Bj\nX9lnQtUGBvXMo6D4vqKOVejEOjfK2DVvuVJEGtbDmwJ9ljQGklybSJ19ohEujdpV\n84NVY9LiZGya9F6SaZadOPKqAvYgFwmWRfOsdiBIXlJ9FXodcd4oE4q1AFlX3Ogq\n+YyMY1xY4spSn2RxLJc8AfI=\n-----END PRIVATE KEY-----\n";


// The ID of the spreadsheet where you'll publish the data

const char spreadsheetId[] = "1g_iSECpZtVPYQIcYqwiuH6AiCyx23LEwCrdgco5Elpg";


// Timer variables

unsigned long lastTime = 0;

unsigned long timerDelay = 3000;


// Token Callback function

void tokenStatusCallback(TokenInfo info);


// NTP server to request epoch time

const char* ntpServer = "pool.ntp.org";


// Variable to save current epoch time

unsigned long epochTime;


// Function that gets current epoch time

unsigned long getTime() {

  time_t now;

  struct tm timeinfo;

  if (!getLocalTime(&timeinfo)) {

    //Serial.println("Failed to obtain time");

    return (0);

  }

  time(&now);

  return now;

}


void setup() {

  Serial.begin(115200);


  configTime(0, 0, ntpServer); //Configure time


  GSheet.printf("ESP Google Sheet Client v%s\n\n", ESP_GOOGLE_SHEET_CLIENT_VERSION);


  //Wi-fi connection

  WiFi.mode(WIFI_STA);

  WiFiManager wm;

  bool res;

  // res = wm.autoConnect(); // auto generated AP name from chipid

  res = wm.autoConnect("AlternatoreIOT"); // anonymous ap

  //res = wm.autoConnect("AutoConnectAP", "password"); // password protected ap


  pinMode(LED_BUILTIN, OUTPUT);


  if (!res) {

    Serial.println("Failed to connect");

    // ESP.restart();

  }

  else {

    //if you get here you have connected to the WiFi

    Serial.println("connected...yeey :)");

    digitalWrite(LED_BUILTIN, HIGH);

    delay(1000);

    digitalWrite(LED_BUILTIN, LOW);

    delay(1000);

    digitalWrite(LED_BUILTIN, HIGH);

    delay(1000);

    digitalWrite(LED_BUILTIN, LOW);

  }

  //Hall sensor

  pinMode(hall_pin, INPUT);


  //ACS712 sensor

  pinMode(sensorIn, INPUT);


  // Set the callback for Google API access token generation status (for debug only)

  GSheet.setTokenCallback(tokenStatusCallback);


  // Set the seconds to refresh the auth token before expire (60 to 3540, default is 300 seconds)

  GSheet.setPrerefreshSeconds(10 * 60);


  // Begin the access token generation for Google API authentication

  GSheet.begin(CLIENT_EMAIL, PROJECT_ID, PRIVATE_KEY);

}


void loop() {

  //Wi-fi connection

  unsigned long currentMillis = millis();

  // if WiFi is down, try reconnecting every CHECK_WIFI_TIME seconds

  if ((WiFi.status() != WL_CONNECTED) && (currentMillis - previousMillis >= interval)) {

    Serial.print(millis());

    Serial.println("Reconnecting to WiFi...");

    WiFi.disconnect();

    WiFi.reconnect();

    previousMillis = currentMillis;

  }

  else if (WiFi.status() == WL_CONNECTED) {

    digitalWrite(LED_BUILTIN, HIGH);

  }

  else {

    digitalWrite(LED_BUILTIN, LOW);

  }

  // Call ready() repeatedly in loop for authentication checking and processing

  bool ready = GSheet.ready();


  if (ready && millis() - lastTime > timerDelay) {

    lastTime = millis();


    FirebaseJson response;


    Serial.println("\nAppend spreadsheet values...");

    Serial.println("----------------------------");


    FirebaseJson valueRange;


    //Hall sensor

    float hall_count = 1.0;

    float start = micros();

    bool on_state = false;

    // counting number of times the hall sensor is tripped

    // but without double counting during the same trip

    while (true) {

      if (digitalRead(hall_pin) == 0) {

        if (on_state == false) {

          on_state = true;

          hall_count += 1.0;

        }

      }

      else {

        on_state = false;

      }


      if (hall_count >= hall_thresh) {

        break;

      }

    }



    float end_time = micros();

    time_passed = ((end_time - start) / 1000000.0);

    rpm_val = (hall_count / time_passed) * 60.0;

    epochTime = getTime();


    //ACS712

    Voltage = getVPP();

    VRMS = (Voltage / 2.0) * 0.707; //root 2 is 0.707

    AmpsRMS = ((VRMS * 1000) / mVperAmp) - 0.3; //0.3 is the error I got for my sensor

    delay (100);


    valueRange.add("majorDimension", "COLUMNS");

    valueRange.set("values/[0]/[0]", epochTime);

    valueRange.set("values/[1]/[0]", rpm_val);

    valueRange.set("values/[2]/[0]", time_passed);

    valueRange.set("values/[3]/[0]", AmpsRMS);

    valueRange.set("values/[4]/[0]", VRMS);


    // For Google Sheet API ref doc, go to https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append

    // Append values to the spreadsheet

    bool success = GSheet.values.append(&response /* returned response */, spreadsheetId /* spreadsheet Id to append */, "Foglio1!A2" /* range to append */, &valueRange /* data range to append */);

    if (success) {

      response.toString(Serial, true);

      valueRange.clear();

    }

    else {

      Serial.println(GSheet.errorReason());

    }

    Serial.println();

    Serial.println(ESP.getFreeHeap());

  }

}


float getVPP() {

  float result;

  int readValue;                // value read from the sensor

  int maxValue = 0;             // store max value here

  int minValue = 4096;          // store min value here ESP32 ADC resolution


  uint32_t start_time = millis();

  while ((millis() - start_time) < 1000) //sample for 1 Sec

  {

    readValue = analogRead(sensorIn);

    // see if you have a new maxValue

    if (readValue > maxValue)

    {

      /*record the maximum sensor value*/

      maxValue = readValue;

    }

    if (readValue < minValue)

    {

      /*record the minimum sensor value*/

      minValue = readValue;

    }

  }


  result = ((maxValue - minValue) * 3.3) / 4096.0; // Subtract min from max - ESP32 ADC resolution 4096


  return result;

}


void tokenStatusCallback(TokenInfo info) {

  if (info.status == token_status_error) {

    GSheet.printf("Token info: type = %s, status = %s\n", GSheet.getTokenType(info).c_str(), GSheet.getTokenStatus(info).c_str());

    GSheet.printf("Token error: %s\n", GSheet.getTokenError(info).c_str());

  }

  else {

    GSheet.printf("Token info: type = %s, status = %s\n", GSheet.getTokenType(info).c_str(), GSheet.getTokenStatus(info).c_str());

  }

}