Sida 3 av 3

Re: Robot med helvarvs-servon

Postat: 23 maj 2009, 14:37:18
av squiz3r
Många PIC'ar kan ju skriva till sitt eget programminne, det borde väll AVR'er också kunna tycker jag..? Annars kostar det ju inte mycket med ett 64kbyte eeprom minne. Alternativt ett flashminne, de finns ju väldigt stora för mycket billiga priser!

Re: Robot med helvarvs-servon

Postat: 23 maj 2009, 16:27:30
av Anonym2
Det stämmer nog att Atmega16 kan skriva till sitt eget programminne. Om jag tar 10k därifrån till en karta så blir det typ 70x70 rutor, om det är INT. I Char så blir det typ 100x100. Med 64kb externt minne så blir det ju betydligt mer, ska spawna lite på det...


//Alexander

Re: Robot med helvarvs-servon

Postat: 23 maj 2009, 18:02:44
av squiz3r
Där va en firma som sålde 8Mbit (alltså 1 Mb) flash minnen för 1kr styck! (SPI). Jag kollade på deras hemsida nu, men dem verkar inte ha kvar dem :(

Om du använder ett sånt minne så kan du ha en matris som är 1000 x 1000 om du använder char :D

Kolla i den här tråden: FLASH MINNEN

Re: Robot med helvarvs-servon

Postat: 26 maj 2009, 01:16:12
av Anonym2
Nu har koden finslipats. Programet tar inte längre första vägen som den hittar, utan fortsätter att leta lösningar hela kartan ut. Roboten stannar även, och indikerar med lysdiod ifall den har blivit instängd. Kartan är dessutom utökad till 18x18.

Jag har försökt trimma in servona, så att den kan hålla kursen hjälpligt, men det verkar omöjligt. Alternativen är någon form av encoder, alternativt stegmotorer. Eftersom jag har meckat lite med stegmotorer förr, så tänkte jag bygga om chassits underdel, till att ha 4st stegmotorer istället, dock fortfarande styra differentiellt.

Om man har 4st drivande hjul, istället för 2st och ett "sväng med hjul", så flyttar man ju rotationsaxeln till mitt emellan hjulaxlarna, kanske blir något trögare, men det borde gå. Jag har införskaffat 4st stegmotorer, och ett par ULN2003-kretsar för att styra dessa med. Koden är enkel att anpassa för stegmotorer, bara att skriva om funktionerna "MoveForward" osv...

Bild

Nu till det eviga problemet, hur fäster man hjul/kugghjul/remskivor till stegmotorerna? Dessa är modell "kjell o co" 3mm axel, 24v 280mA. Någon som vågar gissa om dessa klarar av att driva hjul direkt?

//Alexander

Re: Robot med helvarvs-servon

Postat: 26 maj 2009, 06:46:37
av victor_passe
De motorerna suger!
Hur ska du få 24V på din robot?
De är jättesvaga.

Jag har 2st likadana och driver med ULN2803.
Jag har mina för en liten robot.
Jag kan max köra i 2 min sedan blir dem ca 70C och smältlimmet smälter.
Mina orkar bara driva roboten på 20V minst och roboten är en 1*1 dm stor plywood skiva och väger nog sammanlagt 300g.

Jag byggde iof bara min på skoj för att jag inte hade något bättre för mig men jag har svårt att tro att du lyckas bra med de motorerna.

Re: Robot med helvarvs-servon

Postat: 26 maj 2009, 11:50:50
av Anonym2
Hej

Jag tänkte köra ett par gamla RC-ackar, för att få 24V. Har du provat att köra "high-torq" stegning med motorerna, körde du dom med eller utan utväxling, direkt på hjulen? Var dom slöa även vid 24V?


Jag tänkte ta och försöka testa dom de närmsta dagarna, ev. snäckdrev eller ngt sådant kanske.

//Alexander

Re: Robot med helvarvs-servon

Postat: 26 maj 2009, 16:18:07
av matkrig
Nån sorts encoder vore väl roligast!

En grej som funkar perfa är att sätta en randig pappersskiva på insidan av varje hjul och ett par reflexdetektorer som räknar ränderna, de kostar under en tia på elfa (75-344-72)! Så slipper du ändra på ditt snitsiga chassi också.

Re: Robot med helvarvs-servon

Postat: 26 maj 2009, 18:37:50
av victor_passe
Jag körde med ca 1dm(diameter) hjul direkt på axeln.
Och vid 24V orkade de dra roboten men det var ganska precis.
Och jag har provat med "high-torq" men det blev bara mycket varmare.

Och dem är sakta. Jag fick bara upp mina i kanske 3varv/sek och då var den helt kraftlös, snuddade man den så stannade den.

Re: Robot med helvarvs-servon

Postat: 29 maj 2009, 20:14:49
av Anonym2
Nu har jag testat stegmotorerna, precis som påpekats är det inga kraftpaket direkt, men dom borde fungera om man monterar mindre hjul/utväxling(hoppas...)

Bild

2st stegmotorer och 1st LCD är nu kopplade till kortet, ska börja med chassit, och försöka jaga hjul...


//Alexander

Re: Robot med helvarvs-servon

Postat: 2 juni 2009, 14:05:20
av Anonym2
Visade sig mycket riktigt att stegmotorerna inte kommer i närheten av att orka dra en robot på 2kg. Den utväxling som krävs skulle resultera i att den kör i takt med en snigel...

Någon som vet var man kan få tag i kraftigare stegmotorer, som inte kostar skjortan?


//Alexander

Re: Robot med helvarvs-servon

Postat: 2 juni 2009, 14:39:41
av matkrig
Jag tycker fortfarande att det verkar onödigt med stegmotorer, speciellt om du måste köpa nya. Kör på dina gamla och släng in en encoder för en tia istället.

Re: Robot med helvarvs-servon

Postat: 5 juni 2009, 15:00:37
av Baloo
Har ni inget elektronikskrotlager nånstans där Ni bor. Det brukar ju kunna gå att flirta med dom som jobbar på sånna ställen så man kan få loss lite roliga saker. Det har ju ploppat upp lite varstans nu när allt ska återvinnas och plockas isär. =)

Re: Robot med helvarvs-servon

Postat: 6 juni 2009, 11:56:25
av Anonym2
Det finns något sådant i Malmö har jag för mig, vid sopförbränningsverket. Jag tror dock att det är knepigt att komma in där.

Jag har börjat att fixa ett nytt chassi i plywood(ikeas tidningssamlare), som är större, och större hjulbredd(nogrannare styrning). Där ska även finnas plats för LCDdisplay och lite sådant.

//Alexander

Re: Robot med helvarvs-servon

Postat: 8 juni 2009, 02:34:27
av Anonym2
Nu är den klar!

Det blev mycket enklare för den att hålla kursen med större hjulavstånd. Den arbetar nu efter en karta som är 18x18 rutor stor, och varje ruta är 34x34cm. En lärdom till nästa projekt är att Sharps IR avståndsmätare har en mycket smal "mätstråle". Ping sensor hade varit bättre.

Den fixar dock biffen och går från sovrum till arbetsrum, och navigerar runt alla hinder på vägen. En LCD display listar position och sysselsättning, eller om roboten har blivit instängd.

Bild

WaveFront algoritmen är mycket enkel att arbeta med. Alla andra alternativ som jag har hittat verkar kräva långtgående akademiska kunskaper i ämnet :)

Här är koden om någon undrar

Kod: Markera allt

#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include "lcd.h"

void MoveBackward(int);
void MoveForward(int);
void RotateLeft(void);
void RotateRight(void);
void FindLowest(void);
void RoutePath(void);
void GotoNext(void);
void ClearMap(void);

int rx = 16;					//robot x position
int ry = 4;	
int gx = 2;
int gy = 4;				//robot y position
int direction = 1;		//robot direction
int lowest;				//check for lowest number
int proxim;					//starting pos is in vicinity
int x = 1;					//Set start, upper left
int y = 1;					//corner
int quit = 0;				//path found
int distance;				//distance
int value;
int test = 800;
int left;
int right;
int upp;
int down;
int light;
int qr;
int test;

char cx[4];		//for LCD rx
char cy[4];		//for LCD ry



int  map[18][18] = {{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},			//0 = unoccupied, 1 = wall, 2 = goal, 254 = robot start
					{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
					{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
					{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
					{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
					{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
					{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
					{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
					{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
					{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
					{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
					{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
					{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
					{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
					{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
					{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
					{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
					{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}};

int main(void)
{




map[rx][ry] = 254;			//set startposition
map[gx][gy] = 2;			//set goalposition
//TIMERS

TCCR1B |=(1<<CS10);		//Start timer at F/CPU

//ADC

ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
ADMUX |= ((1 << REFS0)|(1 << REFS1));
ADCSRA |= (1 << ADATE);
ADCSRA |= (1 << ADEN);
ADCSRA |= (1 << ADSC);

//PORTS

DDRD = 255;				//Set Port D as Output
DDRC = 0;				//Set Port C as Input
PORTC|=_BV(0);			//Enable internal PullUpp on PortC, Pin 0

lcd_init(LCD_DISP_ON);





RoutePath();

while(1)
	{
	
	FindLowest();
	GotoNext();
	}

}


void GotoNext(void)
{
lcd_clrscr();
itoa(rx,cx,10);
itoa(ry,cy,10);
lcd_gotoxy(0,0);
lcd_puts("x:");
lcd_gotoxy(0,1);
lcd_puts("y:");
lcd_gotoxy(2,0);
lcd_puts(cx);
lcd_gotoxy(2,1);
lcd_puts(cy);

if(lowest ==1 && direction ==1)
	{
	MoveForward(3);
	if(qr != 1)
		rx = rx -1;
	qr = 0;
	}
else if(lowest == 1 && direction == 2)
	{
	RotateLeft();
	direction = lowest;
	MoveForward(3);
	if(qr != 1)
		rx = rx -1;
	qr = 0;
	}
else if(lowest == 1 && direction == 3)
	{
	RotateRight();
	RotateRight();
	direction = lowest;
	MoveForward(3);
	if(qr != 1)
		rx = rx -1;
	qr = 0;
	}
else if(lowest == 1 && direction == 4)
	{
	RotateRight();
	direction = lowest;
	MoveForward(3);
	if(qr != 1)
		rx = rx -1;
	qr = 0;
	}


// if lowest = 2


if(lowest ==2 && direction ==2)
	{
	MoveForward(3);
	if(qr != 1)
		ry = ry +1;
	qr = 0;
	}
else if(lowest == 2 && direction == 3)
	{
	RotateLeft();
	direction = lowest;
	MoveForward(3);
	if(qr != 1)
		ry = ry +1;
	qr = 0;
	}
else if(lowest == 2 && direction == 4)
	{
	RotateRight();
	RotateRight();
	direction = lowest;
	MoveForward(3);
	if(qr != 1)
		ry = ry +1;
	qr = 0;	

	}
else if(lowest == 2 && direction == 1)
	{
	RotateRight();
	direction = lowest;
	MoveForward(3);
	if(qr != 1)
		ry = ry +1;
	qr = 0;
	}

// if lowest = 3


if(lowest ==3 && direction ==3)
	{
	MoveForward(3);
	if(qr != 1)
		rx = rx +1;
	qr = 0;
	}
else if(lowest == 3 && direction == 4)
	{
	RotateLeft();
	direction = lowest;
	MoveForward(3);
	if(qr != 1)
		rx = rx +1;
	qr = 0;
	}
else if(lowest == 3 && direction == 2)
	{
	RotateRight();
	direction = lowest;
	MoveForward(3);
	if(qr != 1)
		rx = rx +1;
	qr = 0;
	}
else if(lowest == 3 && direction == 1)
	{
	RotateRight();
	RotateRight();
	direction = lowest;
	MoveForward(3);
	if(qr != 1)
		rx = rx +1;
	qr = 0;
	}

// if lowest = 4


if(lowest ==4 && direction ==4)
	{
	MoveForward(3);
	if(qr != 1)
		ry = ry -1;
	qr = 0;
	}
else if(lowest == 4 && direction == 1)
	{
	RotateLeft();
	direction = lowest;
	MoveForward(3);
	if(qr != 1)
		ry = ry -1;
	qr = 0;
	}
else if(lowest == 4 && direction == 2)
	{
	RotateRight();
	RotateRight();
	direction = lowest;
	MoveForward(3);
	if(qr != 1)
		ry = ry -1;
	qr = 0;
	}
else if(lowest == 4 && direction == 3)
	{
	RotateRight();
	direction = lowest;
	MoveForward(3);
	if(qr != 1)
		ry = ry -1;
	qr = 0;
	}

if(map[rx][ry] == 2)
	{
	lcd_clrscr();
	lcd_puts("goal found");
	while(1)
		{
		}
	}



}



void FindLowest(void)
{
lcd_clrscr();
lcd_puts("SEARCH LOWEST");
if(map[rx-1][ry] <=1)
	upp = 255;
else upp = map[rx-1][ry];

if(map[rx][ry-1] <=1)
	left = 255;
else left = map[rx][ry-1];

if(map[rx+1][ry] <=1)
	down = 255;
else down = map[rx+1][ry];

if(map[rx][ry+1] <=1)
	right = 255;
else right = map[rx][ry+1];


if(right <= upp && right <= left && right <= down)
	lowest = 2;
if(down <= upp && down <= left && down <= right)
	lowest = 3;
if(left <= upp && left <= right && left <= down)
	lowest = 4;
if(upp <= right && upp <= left && upp <= down)
	lowest = 1;
if(upp == right && right == down && down == left && left == upp)		//if trapped
	{
	while(1)
		{
		lcd_clrscr();
		lcd_puts("TRAPPED");
		}
	}



}



void RoutePath(void)
	{

	lcd_clrscr();
	lcd_puts("TRAPPED!");
	x = 1;
	y = 1;
	while(1)			//mapping starts
		{
 		value = 0;
	


	
	if(map[x][y] == 0)				//if square doesnt have number since before
			{
			if(map[x-1][y] <= 253)	
				{							//check left if not wall or robot startingpos
				if(map[x-1][y] >= 2)	
					value = map[x-1][y];		//save number on the one on the left
				}	
			if(map[x-1][y] == 254) 			//check if robot startpos is close
				proxim = 1;





			if(map[x+1][y] <= 253)	
				{							//check right if not wall or robot startingpos
				if(map[x+1][y] >= 2)	
					{
					if(value >= map[x+1][y])
						value = map[x+1][y];		//save number on the one on the left
					if(value == 0)
						value = map[x+1][y];	
					}
				
				}	
			if(map[x+1][y] == 254) 			//check if robot startpos is close
				proxim = 1;




			if(map[x][y-1] <= 253)	
				{							//check above not wall or robot startingpos
				if(map[x][y-1] >= 2)	
					{
					if(value >= map[x][y-1])
						value = map[x][y-1];		//save number on the one on the left
					if(value == 0)
						value = map[x][y-1];
					}
				}	
			if(map[x][y-1] == 254) 			//check if robot startpos is close
				proxim = 1;

			
			

			if(map[x][y+1] <= 253)	
				{							//check below if not wall or robot startingpos
				if(map[x][y+1] >= 2)	
					{
					if(value >= map[x][y+1])
						value = map[x][y+1];		//save number on the one on the left
					if(value == 0)
						value = map[x][y+1];
					}
				}	
			if(map[x][y+1] == 254) 			//check if robot startpos is close
				proxim = 1;
				}
				

			if(value >= 3)		//check if map coordinate is set
				{
				if(proxim == 1)
					quit = 1;				//and if robot start pos is next
				}							//path found.
			if(value > 0)
				{
				value++;
				map[x][y] = value;		
				}
			proxim = 0;



			if(x>=17)					//next square below
				{
				x = 1;
				y++;
				}
			else if(x<=16)				//next column to the right
				x++;

			if(y>=17 && x>=17)			//check if hole map has been scaned once, if so, start over
				{
				x=1;
				y=1;
				}

			if(quit == 1 && y>=16)
				goto finish;
	
	}
finish:;
quit = 0;


}






void MoveForward(int sec)
{
distance = ADCL + (ADCH<<8);

if(distance >= 320)
	{
	lcd_clrscr();
	lcd_puts("PATH BLOCKED");
	ClearMap();
	RoutePath();
qr = 1;
goto end;
	}

int gang = 0;
int P = 0;
	while((gang/50) <= sec)
		{
		gang = gang + 1;
		PORTD &=~(1<<0);
		PORTD &=~(1<<1);
			while(P <= 12)
				{
				while(TCNT1 <= 19000)
					{
					}
				P = P + 1;
				TCNT1 = 0;
				}
			P = 0;
			TCNT1 = 0;
		PORTD |=(1<<0);
		PORTD |=(1<<1);
	while(TCNT1 <= 9300)
				{
		}
	PORTD &=~(1<<0);
	TCNT1 = 0;
	while(TCNT1 <= 1040)
		{
		}
	PORTD &=~(1<<1);
	TCNT1 = 0;
		}

TCNT1 = 0;
end:;

}

void MoveBackward(int sec)
{
int gang = 0;
int P = 0;
	while((gang/20) <= sec)
		{
		gang = gang + 1;
		PORTD &=~(1<<0);
		PORTD &=~(1<<1);
			while(P <= 12)
				{
				while(TCNT1 <= 19000)
					{
					}
				P = P + 1;
				TCNT1 = 0;
				}
			P = 0;
			TCNT1 = 0;
		PORTD |=(1<<0);
		PORTD |=(1<<1);
	while(TCNT1 <= 9300)
			{
			}
	PORTD &=~(1<<1);
	TCNT1 = 0;
	while(TCNT1 <= 1050)
		{
		}
	PORTD &=~(1<<0);
	TCNT1 = 0;
}
}

void RotateRight(void)
{
int gang = 0;
int P = 0;
	while(gang <= 135)
		{
		gang = gang + 1;
		PORTD &=~(1<<0);
		PORTD &=~(1<<1);
		while(P <= 12)
			{
			while(TCNT1 <= 19000)
				{
				}

			P = P + 1;
			TCNT1 = 0;

			}

		P = 0;
		TCNT1 = 0;
		PORTD |=(1<<0);
		PORTD |=(1<<1);
		while(TCNT1 <= 9300)
			{
			}
		PORTD &=~(1<<0);
	TCNT1 = 0;
		while(TCNT1 <= 1)
			{
			}
		PORTD &=~(1<<1);
		TCNT1 = 0;
		}
}

void RotateLeft(void)
{
int gang = 0;
int P = 0;
	while(gang <=120)
		{
		gang = gang + 1;
		PORTD &=~(1<<0);
		PORTD &=~(1<<1);
		while(P <= 12)
			{
			while(TCNT1 <= 19000)
				{
				}

			P = P + 1;
			TCNT1 = 0;

			}

		P = 0;
		TCNT1 = 0;
		PORTD |=(1<<0);
		PORTD |=(1<<1);
		while(TCNT1 <= 10350)
			{
			}
		PORTD &=~(1<<0);
		TCNT1 = 0;
		while(TCNT1 <= 1)
			{
			}
		PORTD &=~(1<<1);
		TCNT1 = 0;
		}
}

void ClearMap(void)
	{
	lcd_clrscr();
	lcd_puts("CLEARING MAP");
	if(direction == 1)
		map[rx-1][ry] = 1;
	if(direction == 2)
		map[rx][ry+1] = 1;
	if(direction == 3)
		map[rx+1][ry] = 1;
	if(direction == 4)
		map[rx][ry-1] = 1;
	x = 1;
	y = 1;
	while(y<=9)
		{
		if(map[x][y] >=3 && map[x][y] != 254)
			map[x][y] = 0;
		if(map[x][y] == 3)
			map[x][y] = 0;
		if(x<17)
			x++;
		else
			{
			x=1;
			y++;
			}
		}
	}