Antweight motor control – Baby-O

From: http://garya.org.uk/software/embedded-c/antweight-speed-controller

/*
 * SpeedController.c
 *
 *  Created on: 19 Aug 2013
 *      Author: Gary Aylward
 *   Copyright: Gary Aylward, 2013
 *     Website: http://garya.org.uk
 *     License: Creative Commons BY-SA 3.0
 *
 *     http://creativecommons.org/licenses/by-sa/3.0/
 *
 *     Pololu Orangutan library (c) Pololu Corporation, licensed under CC-BY-SA 3.0
 *
 *     1.0 19/08/2013 Original release
 *     1.1 25/08/2013 Fixed battery monitor filter bug
 */

/*
 * Antweight R/C speed controller using Pololu Baby Orangutan board
 *
 * Set linker to use pololu_atmega328p library.
 *
 * Module pinouts are defined below, the settings used allow other pins to be used for
 * further R/C channels, extra PWM outputs, UART etc.
 * The battery voltage is fed to the ADC via a potential divider so that the ADC sees
 * the voltage of a single cell. If the under-voltage lockout is not required, connect
 * the ADC input to Vcc or redefine dCELL_MV below.
 *
 * Mixing is set up for an R/C transmitter with the following characteristics:
 * Channel 1 = Left/Right, Right = longer pulses
 * Channel 2 = Forwards/Reverse, Reverse = longer pulses
 *
 * Motors are connected with +ve terminal connected to M1B / M2B, -ve to M1A / M2A
 * Motors turn clockwise (when viewed from shaft end) with positive voltage
 */

#include <pololu/orangutan.h>

#ifndef F_CPU
#define F_CPU	20000000	// Baby Orangutan runs at 20MHz
#endif

#define dCHANNEL1	IO_C0	// R/C Ch1 input pin
#define dCHANNEL2	IO_C1	// R/C Ch2 input pin
#define	dLED		IO_D1	// LED output pin
#define dADC_CHANNEL	6	// ADC battery monitor channel

#define dZERO		1500	// Nominal pulse width
#define dMAX		2000	// Max pulse width
#define dMIN		1000	// Min pulse width
#define dMAX_PULSE	2200	// Pulse width for error detection
#define dMIN_PULSE	800		// Pulse width for error detection
#define dTIMEOUT	30000	// 30ms timeout on R/C pulses
#define dMAX_SPEED	250		// Max speed setting
#define dMIN_SPEED	-250	// Min speed setting

#define dFILTER_SIZE	600	// Length of under-voltage detection filter, 6 steps per ms
#define dCELL_MV	2750	// Minimum cell voltage in mV


int main()
{
	unsigned int vVoltage = 0;			// Battery cell voltage measurement
	unsigned char vUnderVolt = 0;		// Under-voltage error flag
	unsigned long vFilter = 0;			// Under-voltage filter counter
	struct PulseInputStruct vPulseInfo;	// Orangutan library pulse structure
	unsigned long vPulseLength = 0;		// Pulse length in ticks
	unsigned char vState = 0;			// Current pulse state
	unsigned long vPulseCh1 = dZERO;	// Channel 1 pulse in ms
	unsigned long vPulseCh2 = dZERO;	// Channel 2 pulse in ms
	int vLeftSpeed;						// Left motor speed
	int vRightSpeed;					// Right motor speed
	unsigned char vError = 1;			// Error flag

	// Configure pins as pulse input channels
	pulse_in_start((unsigned char[]) {dCHANNEL1, dCHANNEL2}, 2);
	// Enable internal pull-ups on R/C input channels
	set_digital_input(dCHANNEL1, PULL_UP_ENABLED);
	set_digital_input(dCHANNEL2, PULL_UP_ENABLED);
	// Initialise LED to off
	set_digital_output(dLED, 0);
	//Set ADC to 10-bit mode
	set_analog_mode(MODE_10_BIT);

	while(1)
	{
		if (analog_is_converting() == 0)
		{
			// Start a new conversion if one isn't already running
			start_analog_conversion(dADC_CHANNEL);
		}
		// Get time since last edge on R/C channel 1
		get_current_pulse_state(0, &vPulseLength, &vState);
		if (pulse_to_microseconds(vPulseLength) >= dTIMEOUT)
		{
			vError = 1; // R/C timeout - signal lost
		}
		else
		{
			get_pulse_info(0, &vPulseInfo); // get pulse info for R/C channel 1
			if (vPulseInfo.newPulse & HIGH_PULSE)
			{
				vPulseCh1 = pulse_to_microseconds(vPulseInfo.lastHighPulse);
				if ((vPulseCh1 > dMAX_PULSE) || (vPulseCh1 < dMIN_PULSE))
				{
					vError = 1;	// Pulse is too long or too short
				}
				else
				{
					vError = 0;
					if (vPulseCh1 > dMAX)
					{
						vPulseCh1 = dMAX;
					}
					if (vPulseCh1 < dMIN)
					{
						vPulseCh1 = dMIN;
					}
				}
			}
		}
		// Get time since last edge on R/C channel 2
		get_current_pulse_state(1, &vPulseLength, &vState);
		if (pulse_to_microseconds(vPulseLength) >= dTIMEOUT)
		{
			vError = 1;	// R/C timeout - signal lost
		}
		else
		{
			get_pulse_info(1, &vPulseInfo); // get pulse info for R/C channel 2
			if (vPulseInfo.newPulse & HIGH_PULSE)
			{
				vPulseCh2 = pulse_to_microseconds(vPulseInfo.lastHighPulse);
				if ((vPulseCh2 > dMAX_PULSE) || (vPulseCh2 < dMIN_PULSE))
				{
					vError = 1;	// Pulse is too long or too short
				}
				else
				{
					vError = 0;
					if (vPulseCh2 > dMAX)
					{
						vPulseCh2 = dMAX;
					}
					if (vPulseCh2 < dMIN)
					{
						vPulseCh2 = dMIN;
					}
				}
			}
		}
		if (analog_is_converting() == 0)
		{
			// If ADC conversion is finished, check the battery voltage
			vVoltage = analog_conversion_result_millivolts();
			if (vVoltage < dCELL_MV)
			{
				if (vFilter >= dFILTER_SIZE)
				{
					// Filter has timed out, leave the fault flag set
					vFilter = dFILTER_SIZE;	// Prevent filter count from overflowing
					vUnderVolt = 1;	// Set fault flag
				}
				else
				{
					vFilter++;	// Increment filter count
					vUnderVolt = 0;	// Clear fault flag
				}
			}
			else
			{
				vFilter = 0;	// Reset filter if voltage is above limit
			}
		}
		// Calculate motor speeds
		vLeftSpeed = ((vPulseCh2 - dZERO) - (vPulseCh1 - dZERO)) / 2;
		vRightSpeed = (-(vPulseCh2 - dZERO) - (vPulseCh1 - dZERO)) / 2;
		// Limit maximum speeds
		if (vLeftSpeed > dMAX_SPEED)
		{
			vLeftSpeed = dMAX_SPEED;
		}
		else if (vLeftSpeed < dMIN_SPEED)
		{
			vLeftSpeed = dMIN_SPEED;
		}
		if (vRightSpeed > dMAX_SPEED)
		{
			vRightSpeed = dMAX_SPEED;
		}
		else if (vRightSpeed < dMIN_SPEED)
		{
			vRightSpeed = dMIN_SPEED;
		}
		if ((vUnderVolt == 1) || (vError == 1))
		{
			// Stop motors and light LED if a fault exists
			set_m1_speed(0);
			set_m2_speed(0);
			set_digital_output(dLED, 1);
		}
		else
		{
			// Set motor speeds and turn off LED
			set_m1_speed(vLeftSpeed);
			set_m2_speed(vRightSpeed);
			set_digital_output(dLED, 0);
		}
	}
}

Lipo batteries 1s cells for 70p!

Following a nice sale on Hobbyking, i decided to buy some new antweight batteries.  At $0.59 – $0.99 each, these little beauties should hopefully reduce my weight down, without affecting actual play time.

IMAG7531

I found them whilst looking into the bargain bins of hobbyking (INTERNATIONAL STORE)

 http://www.hobbyking.com/hobbyking/store/bargain_bins_rc_hobby_products.asp?bin=1

My Ant is currently weighing in at 170g so by reducing weight and using my milling machine to fill out some nuice parts, i can reduce overall weight by 30g.

The batteries are the slot in type so i either make/buy a connector for them (common to buy landing gear/battery pack slots as a whole and break it down) or remove the existing connector and replace it with a more standard one.

I prefer to keep this connector as its handy, and i can just get the set charger for it, but i also have the other chargers for the other standard JST type.

 

Hmmm… run to ebay to check prices and options i think

 

The batteries are an assortment of Nano-Tech 160mAh 25c 1s, Nano-Tech 160mAh 25-45c 1s, Nano-Tech 130mAh 25c 1s all 3.7v and slot in connectors, but in both 2 types of connectors – one new and old style heli.

 

I have just purchased a charger for these battery, which are also handy for charging my other Lipos single cells.
IMAG7535[1]

I also have purchased some battery holders, something i can make with the 3d printer but for ease i thought i would buy these.

http://www.hobbyking.com/hobbyking/store/__19262__Nine_Eagles_Battery_Holder.html

 

Curiosity, you can also buy these direct from E-SKY, for a mere $1.04 which i had wanted to buy, and buy 30 of them so i can resell to the antweight community, but they only have 1 in stock, and the minimum $7 postage didnt warrant buying 1.

http://www.esky-heli.com/nine-eagles-ne401777008a-battery-holder.html

Antweight robot design V3

Hi all, just thought i would show you the latest in design of my Ant, name to be decieded, but will be a goodan, i have some possibilities, just need to check if there not taken!

This is a mock up design in solidworks, but i also have it printed and fited.

 

I have a controller design ready and now i have the design as i like i can start to design the PCB and get aluminium for the chasis walls 🙂

 

Let me know what you think

 

Natantv3

Admesh program to fix broken STL files

I attempted to open the tantillus stl file for top corner front left but sadly it failed in lic3r saying it had no slices or something, and Bill20r3 and teepee on IRC #Reprap explained about Admesh program.

A commad bassed programme, it fixes / translates rotates etc stl files.

to download:
bill20r3> admesh seems to have fixed it just fine, fwiw.
admesh?
admesh is an open source program for repairing, translating and processing STL meshes. It’s very fast and almost as old as 3D printing. https://sites.google.com/a/varlog.com/www/admesh-htm

if this is down due to server issues go to:
http://ftp.de.debian.org/debian/pool/main/a/admesh/
and download
admesh_0.95.orig.tar.gz 12-Oct-1998 20:52 50K file.

Roboteernat: bottom of the page https://sites.google.com/a/varlog.com/www/admesh-htm – the small arrow pointing down

download the file and save to desktop.

open command prompt window and change directory to point to admesh folder

save the broken stl file needed t be fixed ithin the admesh folder and confirm it id there by using cmd window and typing 'dir' to list the files in the directory

Once it is there, we can fx it.

Type

admesh --write-binary-stl=file_admesh.stl file.stl

where file_admesh.stl is the file output name
and file.stl is the name of the file to be fixed

Here is an example print screened for the future 🙂

the file ‘Corner_top_front_left(1).stl has been fixed and saved as Top_corner.stl in the admesh folder.

All slicing fine now 😀

Retraction settings

After a while my retractions settings were not looking great. looking at slic3r a bi more closely, i realised the settings for retraction speed was in mm/s not mm/min, therefore the setting of 30 was causing the stepper to screetch!
i reduced this down to 4mm/s and 4mm retraction which was painfully slow, so a quick q on REPREP IRC channel brought Dreamscape74 suggesting their settings.

Now retraction is set at 14mm/s and 2mm retraction length.

Now onto the brige test…