Difference between revisions of "DIY Lawnmower 2023"

From cod3v
Line 60: Line 60:


import drawsvg as draw
import drawsvg as draw
import math as math


d = draw.Drawing(300, 300, origin='center')
def outline(r1, width, t1, t2):
    #Use degrees
    pi = 3.14159
    r2 = r1 + width
    d.append(draw.ArcLine(0, 0, r1, t1, t2,
            stroke='black', stroke_width=1, fill='none', fill_opacity=0))
    d.append(draw.ArcLine(0, 0, r2, t1, t2,
            stroke='black', stroke_width=1, fill='none', fill_opacity=0))


#Arcline(x0, y0, radius, angle0, angle1 )
    #Convert to rads
    t1 = -t1*2*pi/360
    t2 = -t2*2*pi/360
    d.append(draw.Lines( r1*math.cos(t1), r1*math.sin(t1),
                        r2*math.cos(t1), r2*math.sin(t1),
                        close=False, fill='none', stroke='black'))
    d.append(draw.Lines( r1*math.cos(t2), r1*math.sin(t2),
                        r2*math.cos(t2), r2*math.sin(t2),
                        close=False, fill='none', stroke='black'))




#Draw the center hole
maxAngle = 60
d.append(draw.ArcLine(0, 0, 5, 0, 360,
 
        fill='red', fill_opacity=1))
# Draw multiple circular arcs
width = 4          # mm
diff = 10          #
diff_center = 10  #Extra difference from the center hole
radius_center = 20 #mm
 
d = draw.Drawing(400, 400, origin=( -2 -radius_center, -400 +1 + radius_center))




maxAngle = 360/2
#Draw the center hole
maxAngle = 100
d.append(draw.ArcLine(0, 0, radius_center, 0, 360,
        fill='nore', stroke='black', fill_opacity=0))


# Draw multiple circular arcs
stroke = 15
radius = 2*stroke


#
# 1st row
#
period = 2 #(one black strip, one white strip)
period = 2 #(one black strip, one white strip)
phaseshift = 0
phaseshift = 0
d.append(draw.ArcLine(0, 0, radius, 0, maxAngle/period,
r1 = radius_center + diff_center + diff
        stroke='red', stroke_width=stroke, fill='none', fill_opacity=0.2))
t1 = 0
 
t2 = maxAngle/period
outline(r1, width, t1, t2)


#
# 2nd row
#
period = 2 #(one black strip, one white strip)
period = 2 #(one black strip, one white strip)
phaseshift = maxAngle/(2*period)  ##90 degrees
phaseshift = maxAngle/(2*period)  ##90 degrees
d.append(draw.ArcLine(0, 0, radius+stroke, 0+phaseshift, maxAngle/period+phaseshift,
r1 = r1 + width + diff
        stroke='red', stroke_width=stroke, fill='none', fill_opacity=0.2))
t1 = phaseshift
 
t2 = maxAngle/period + phaseshift
outline(r1, width, t1, t2)


#
# 3rd row
#
period = 4 #(one black strip, one white strip)
period = 4 #(one black strip, one white strip)
phaseshift = maxAngle/(2*period)                    ## 45 deg
phaseshift = maxAngle/(2*period)                     
d.append(draw.ArcLine(0, 0, radius+2*stroke, 0+phaseshift, maxAngle/period+phaseshift,
r1 = r1 + width + diff
        stroke='red', stroke_width=stroke, fill='none', fill_opacity=0.2))
for i in range(0, 4, 2):
phaseshift = maxAngle/(2*period) + 2*maxAngle/(period)   ## 45+2*90 deg
        phaseshift = maxAngle/(2*period) + i*maxAngle/(period)          
d.append(draw.ArcLine(0, 0, radius+2*stroke, 0+phaseshift, maxAngle/period+phaseshift,
        t1 = phaseshift
         stroke='red', stroke_width=stroke, fill='none', fill_opacity=0.2))
        t2 = maxAngle/period + phaseshift
 
         outline(r1, width, t1, t2)


#
# 4th row;
#
period = 8 #(one black strip, one white strip)
period = 8 #(one black strip, one white strip)
phaseshift = maxAngle/(2*period)                    ## 22.5 deg
r1 = r1 + width + diff
d.append(draw.ArcLine(0, 0, radius+3*stroke, 0+phaseshift, maxAngle/period+phaseshift,
for i in range(0, 8, 2):
        stroke='red', stroke_width=stroke, fill='none', fill_opacity=0.2))
        phaseshift = maxAngle/(2*period)+i*maxAngle/(period)
phaseshift = maxAngle/(2*period)+2*maxAngle/(period)
         t1 = phaseshift
d.append(draw.ArcLine(0, 0, radius+3*stroke, 0+phaseshift, maxAngle/period+phaseshift,
         t2 = maxAngle/period + phaseshift
         stroke='red', stroke_width=stroke, fill='none', fill_opacity=0.2))
         outline(r1, width, t1, t2)
phaseshift = maxAngle/(2*period)+4*maxAngle/(period)
d.append(draw.ArcLine(0, 0, radius+3*stroke, 0+phaseshift, maxAngle/period+phaseshift,
         stroke='red', stroke_width=stroke, fill='none', fill_opacity=0.2))
phaseshift = maxAngle/(2*period)+6*maxAngle/(period)
d.append(draw.ArcLine(0, 0, radius+3*stroke, 0+phaseshift, maxAngle/period+phaseshift,
         stroke='red', stroke_width=stroke, fill='none', fill_opacity=0.2))
 


#
#
# Print it
# Print it
#
#
d.set_pixel_scale(2)  # Set number of pixels per geometry unit
d.set_pixel_scale(2)  # Set number of pixels per geometry unit
#d.set_render_size(400, 200)  # Alternative to set_pixel_scale
#d.set_render_size(400, 200)  # Alternative to set_pixel_scale
d.save_svg('example.svg')
d.save_svg('gray.svg')
d.save_png('example.png')
d.save_png('gray.png')


# Display in Jupyter notebook
# Display in Jupyter notebook
#d.rasterize()  # Display as PNG
#d.rasterize()  # Display as PNG
d  # Display as SVG
d  # Display as SVG
print( 'Total width: ', r1 + width, ' mm' )
</syntaxhighlight>
</syntaxhighlight>



Revision as of 02:34, 22 July 2023

Introduction

My tobe biodiversity destroyer.

2 wheel drive using kids ATV chassis with 3" wheels without differential but with steering, 2x350W motor; speed controller. The grass cutter is a part from an old lawn mower. The ATV is steerable, thus a rotation measurement device is needed so that the motor will not burn.


https://www.kuldnebors.ee/search/search.mec?pob_action=search&search_O_string=atv&search_source=kwc

Arduino + GPS + IMU (Differential GPS).


Consider also

Theory

Steering

Use distance sensor to detect the angle
Gray code with rotary disk

The angles needed are:

The motion of steering is restricted, thus the angle need to be measured. Two easy options:

  1. Use distance sensor (HC-SR04), or
  2. Use rotary encoder (single or multi track gray code)

Add the limit sensors to both.

Distance sensor HC-SR04

Gray code

Include the most significant bit (varies most) to outer circle.

Mechanics.

The position where the rotation angle measurement device is to be inserted.

Python code

Python code to generate the gray code image

#
# Use sxiv to continously display the image 
#
#

import drawsvg as draw
import math as math

def outline(r1, width, t1, t2):
    #Use degrees
    pi = 3.14159
    r2 = r1 + width
    d.append(draw.ArcLine(0, 0, r1, t1, t2,
            stroke='black', stroke_width=1, fill='none', fill_opacity=0))
    d.append(draw.ArcLine(0, 0, r2, t1, t2,
            stroke='black', stroke_width=1, fill='none', fill_opacity=0))

    #Convert to rads
    t1 = -t1*2*pi/360
    t2 = -t2*2*pi/360
    d.append(draw.Lines( r1*math.cos(t1), r1*math.sin(t1),
                        r2*math.cos(t1), r2*math.sin(t1),
                        close=False, fill='none', stroke='black'))
    d.append(draw.Lines( r1*math.cos(t2), r1*math.sin(t2),
                        r2*math.cos(t2), r2*math.sin(t2),
                        close=False, fill='none', stroke='black'))


maxAngle = 60

# Draw multiple circular arcs
width = 4          # mm
diff = 10          #
diff_center = 10   #Extra difference from the center hole
radius_center = 20 #mm

d = draw.Drawing(400, 400, origin=( -2 -radius_center, -400 +1 + radius_center))


#Draw the center hole
d.append(draw.ArcLine(0, 0, radius_center, 0, 360,
        fill='nore', stroke='black', fill_opacity=0))


#
# 1st row
#
period = 2 #(one black strip, one white strip)
phaseshift = 0
r1 = radius_center + diff_center + diff
t1 = 0
t2 = maxAngle/period
outline(r1, width, t1, t2)

#
# 2nd row
#
period = 2 #(one black strip, one white strip)
phaseshift = maxAngle/(2*period)  ##90 degrees
r1 = r1 + width + diff
t1 = phaseshift
t2 = maxAngle/period + phaseshift
outline(r1, width, t1, t2)

#
# 3rd row
#
period = 4 #(one black strip, one white strip)
phaseshift = maxAngle/(2*period)                    
r1 = r1 + width + diff
for i in range(0, 4, 2):
        phaseshift = maxAngle/(2*period) + i*maxAngle/(period)           
        t1 = phaseshift
        t2 = maxAngle/period + phaseshift
        outline(r1, width, t1, t2)

#
# 4th row; 
#
period = 8 #(one black strip, one white strip)
r1 = r1 + width + diff
for i in range(0, 8, 2):
        phaseshift = maxAngle/(2*period)+i*maxAngle/(period)
        t1 = phaseshift
        t2 = maxAngle/period + phaseshift
        outline(r1, width, t1, t2)

#
# Print it
#

d.set_pixel_scale(2)  # Set number of pixels per geometry unit
#d.set_render_size(400, 200)  # Alternative to set_pixel_scale
d.save_svg('gray.svg')
d.save_png('gray.png')

# Display in Jupyter notebook
#d.rasterize()  # Display as PNG
d  # Display as SVG

print( 'Total width: ', r1 + width, ' mm' )

Borderline only

Current

Heat Dissipation

Motor

First prototype of the motor bed.
First prototype of the motor bed.

Motor Bed plan: keep is as simple as possible. Note that no welding machine, and other metal tools are scarce.


Torque, Speed, Duty Cycle

The gear is standard 410-9T bicycle chain. Thus, the gears from bicycles will be used for steering and driving. The wheel diameter is 3" (18 cm?), and the front gear is 9 spokes and the maximum rpm is 300. Thus, we have for the back gear



Vevor 24V 350W Nennstrom: 18,4A Brushed Permanentmagnetmotor Gear Reduction Packungsgröße: 22 x 19 x 17 cm (8,66 x 7,48 x 6,69 Zoll) Bruttogewicht: 3,05 kg



9 Zahnrad für Kette Nr. 410, Teilung 12,7 mm. Besonders gut für Heimwerker geeignet, da der Antrieb mit Standard-Fahrradketten (1/2 Zoll Teilung) kompatibel ist

Motor Speed Controller BTS7960

We use BTS7960 based speed controller IBT-2 with max 43 Amps current. The datasheet is available at https://electropeak.com/learn/download/bts7960-43a-motor-driver-datasheet/

Example code from Electropeak or Hessmer

Pins

  • VCC: 5V
  • GND: Ground
  • IS-R: Input signal for detecting high current – Straight rotation
  • IS-L: Input signal for detecting high current – Inverse rotation
  • EN-R: Output Signal for controlling motor direction – Straight rotation
  • EN-L: Output Signal for controlling motor direction – Inverse rotation
  • WM-R: PWM Signal for controlling motor speed – Straight rotation
  • PWM-L: PWM Signal for controlling motor speed – Inverse rotation

Motor pins (High current):

  • M+: Motor Positive; M-: Motor negative
  • B+: Battery positive; * B-: Battery negative


Some instructions:


Extra things and older thoughs.

Use PWM. Feedback? Arduino L298N H-bridge.

Arduino pwm motor controller 300W 36V 20Amps


https://electropeak.com/learn/interfacing-bts7960-43a-high-power-motor-driver-module-with-arduino/

High power dc motor speed controller

Radio controller

How to connect the receiver to Arduino

We chose Flysky FS-i6X RC Radio Sender & FS-IA10B Set 10-Kanal 2,4 GHz AFHDS unit to send and receive data.

// https://medium.com/@werneckpaiva/how-to-read-rc-receiver-signal-with-arduino-54e0447f6c3f
#define CH1 3
#define CH2 5
#define CH3 6
#define CH4 9
#define CH5 10

// Read the number of a given channel and convert to the range provided.
// If the channel is off, return the default value
int readChannel(int channelInput, int minLimit, int maxLimit, int defaultValue){
  int ch = pulseIn(channelInput, HIGH, 30000);
  if (ch < 100) return defaultValue;
  return map(ch, 1000, 2000, minLimit, maxLimit);
}

// Red the channel and return a boolean value
bool redSwitch(byte channelInput, bool defaultValue){
  int intDefaultValue = (defaultValue)? 100: 0;
  int ch = readChannel(channelInput, 0, 100, intDefaultValue);
  return (ch > 50);
}

void setup(){
  Serial.begin(115200);
  pinMode(CH1, INPUT);
  pinMode(CH2, INPUT);
  pinMode(CH3, INPUT);
  pinMode(CH4, INPUT);
  pinMode(CH5, INPUT);
}

int ch1Value, ch2Value, ch3Value, ch4Value;
bool ch5Value;

void loop() {
  ch1Value = readChannel(CH1, -100, 100, 0);
  ch2Value = readChannel(CH2, -100, 100, 0);
  ch3Value = readChannel(CH3, -100, 100, -100);
  ch4Value = readChannel(CH4, -100, 100, 0);
  ch5Value = redSwitch(CH5, false);
  
  Serial.print("Ch1: ");
  Serial.print(ch1Value);
  Serial.print(" Ch2: ");
  Serial.print(ch2Value);
  Serial.print(" Ch3: ");
  Serial.print(ch3Value);
  Serial.print(" Ch4: ");
  Serial.print(ch4Value);
  Serial.print(" Ch5: ");
  Serial.println(ch5Value);
  delay(500);
}


Gear ratios

Lawnmower2013 gearRatioSpeed.svg

Gear ratio

Cutted parts and files

Dimensions

Inkscape's G Code generator, or use JsCut

Rotation detector. Plasma cutter.

  • Center hole: diameter 20 mm.
  • Width: 14 cm.


Steering gear plate:

  • Just two holes
  • Distance between hokes 56 mm.


Driving gear plate

  • Just some holes.