Saturday, September 18, 2021

0000 0000 0111 0011

Rocking the "baby" (L298N II)

We've seen proof of concept for rocking an object using a modified UNO running an ATMega88 instead of an ATMega328, then controlling an L298N motor module which outputs to a dinky little hobbyist robot motor.

The big question is - can it be scaled up to a 12V automotive wiper motor?

The "specs" from my colleague on this project for the type of motion required are - a few seconds of rocking, a few minutes of no motion, control over speed and direction. 

The resulting code is as follows:

/*
   "Rocking the baby"
   Using a modified (ATMega88) Arduino to activate a 12V wiper
   motor via an L298N motor controller off Pins 7-9
   Modified Arduino: https://youtu.be/cfPpaX8V4S8

   The code will need the LowPower library available at:
   https://github.com/rocketscream/Low-Power
   (or you can write your own sleep routines)

   Also needed if you use ATMega88 are two things:
   1) MicroCore from https://github.com/MCUdude/MiniCore
   2) modify LowPower.h by adding ATMega88P to list

   This project can of course use a normal Arduino Uno or Nano etc

   Sketch uses 5498 bytes (67%) of program storage space. Maximum is 8192 bytes.
   Global variables use 81 bytes (7%) of dynamic memory,
   leaving 943 bytes for local variables. Maximum is 1024 bytes.

   A N Peck Mon 02 Aug 2021 19:00:12 AEST
   https://www.youtube.com/channel/UCTm3eCrN6wk-Ozt9ymyKIIg/videos
   https://onecircuit.blogspot.com/
*/

#include "LowPower.h"

// setup variables/constants

// Motor connections (pin numbers)
int enA = 9;
int in1 = 8;
int in2 = 7;
int LEDPin = 6;     // visual indicator of rocking
int BuzzPin = 5;    // audio indicator of rocking

int randomseed = 2901;      // changed in setup via analogRead(A5)

// change these to alter the rocking speed, duration and frequency
byte mspeed = 255;          // motorspeed (0-255)
int l_rocktime = 10;        // lower rocking time in s
int u_rocktime = 30;        // upper rocking time in s
int l_sleeptime = 8;        // lower sleeptime in min
int u_sleeptime = 12;       // lower sleeptime in min
String rotation = "clock";  // "clock" or "counter"

void rock(int rtime) {

  // warning - about to rock
  for (int count = 0; count < 5; count++) {
    tone(BuzzPin, 3200);
    digitalWrite(LEDPin, HIGH);
    delay(500);
    noTone(BuzzPin);
    digitalWrite(LEDPin, LOW);
    delay(1500);
  }

  if (rotation = "clock") {
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
  }
  else {
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
  }

  analogWrite(enA, mspeed);

  rtime = rtime / 2; // two second cycle below

  for (int ocount = 0; ocount < rtime; ocount++) {
    // two seconds of rotation, blinking and buzzing
    digitalWrite(LEDPin, HIGH);
    tone(BuzzPin, 3200);
    delay(100);
    noTone(BuzzPin);
    delay(100);
    tone(BuzzPin, 2500);
    delay(200);
    noTone(BuzzPin);
    delay(600);
    digitalWrite(LEDPin, LOW);
    delay(1000);
  }

  // turn off motor
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
}

void gosleep(int stime) {
  stime = stime * 60; // minutes to seconds
  stime = stime / 8; // seconds to multiples of 8

  for (int count = 0; count < stime; count++) {
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
  }
}

void setup() {
  // randomseed changed
  randomseed = analogRead(A5);

  // Set all the control pins to outputs
  pinMode(enA, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(LEDPin, OUTPUT);
  pinMode(BuzzPin, OUTPUT);

  // Turn off motors - Initial state
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
}

void loop() {

  int rocktime = random(l_rocktime, u_rocktime);  // time rocking (s)
  rock(rocktime);

  int wtime = random(l_sleeptime, u_sleeptime);   // time asleep (min)
  gosleep(wtime);

}

I added an LED and a BUZZER to alert all around that the rocking is about to start (Work, Health and Safety!) - and apart from that all that was needed was the identification of wires on the motor and we were good to go.


No comments:

Post a Comment