Skip to content

Carbot Video Tour and Wireless Programming

April 29, 2015

Today I set up the Olduino Carbot for wireless programming over the XBee link. Because I had already hooked up the XBee to power, ground, and transmit to get the telemetry out, it was just a matter of one more connection to receive data from avrdude on the windows computer. I still have to press reset on the olduino to activate the bootloader but it beats the heck out of shutting everything down to re-program the 1802.
15-04-29 Carbot Wireless
The first video is a walk-around of Carbot showing its various sensors and drivers.

The second video is a demonstration of programming the Olduino wirelessly over the XBee serial link.

The last video is the current state of Carbot on the floor. Slow-ish but no wild turns.

For my records, here’s the code at close of day today.

//olduino carbot simple version Jan 24, 2015
//15-04-26 using <> version of cpu1802spd4port7.h
//15-04-29 cruising speed increased, left turn now 1 ms increments
#include <olduino.h>
#include <nstdlib.h> //supports c d s x l cx
#include <cpu1802spd4port7.h>
#include "softpwm.h"
#include "carbot.h"
#include "pingBN.h"
unsigned int wdist,oldwdist, fprox; // distance to wall on right current & previous, proximity of barrier in front
#define maxfprox 160 //max front barrier proximity
#define maxwdist 30 //min right barrier dist
#define minwdist 25 //min right barrier dist
#define basespeed 255	//was 192
#define lowspeed 64	//was 32
unsigned int sharpy(){  //reads the Sharp GP2D12 IR rangefinder via the MCP3002 ADC, returns raw ADC value
	asm("	dec	sp\n" //make a work area
		"	sex 3\n"	//set x to pc
		"	out 6\n	db 0x68\n"	//send 68 to read channel 0
		"	sex sp\n	inp 6\n" //pick up top bits
		"	ani 3\n	phi 15\n"	//put bits 8&9 of result into return register

		"	sex 3\n"	//set x to pc
		"	out 6\n	db 0xAA\n"	//send pattern to read low bits
		"	sex sp\n	inp 6\n	plo 15\n" //pick up low bits to return register
		"	inc	sp\n"	//restore stack pointer
		"	cretn\n");	//actual return
	return 0;	//dummy return for compiler
}
void killdrive(){//stops both motors
	digitalWrite(pwmb,LOW);//kill power right
	digitalWrite(pwma,LOW);//kill power left
}
void hardleft(){//5 ms turn with left wheel running backwards
	printf("L>\n");
	digitalWrite(pwmb,HIGH);//full power right
	digitalWrite(pwma,HIGH);//full power left
	digitalWrite(bin1,HIGH); digitalWrite(bin2,LOW);
	digitalWrite(ain1,LOW); digitalWrite(ain2,HIGH); //reverse left wheel
	delay(1); //nominal delay only
}

void tooclose(){ //if we are closer than minwdist to the wall on our right side
    if (wdist>oldwdist) {//but going the right way
		analogWrite(pwma,basespeed);analogWrite(pwmb,basespeed); //proceed
		printf(" wf-1 ");
    }
    else{
		analogWrite(pwma,lowspeed);analogWrite(pwmb,basespeed); //bear left
		printf(" wvlft ");
    }
}
void toofar(){//if we are further than minwdist from the wall on our right side
    if (wdist<oldwdist) {//but going the right way
		analogWrite(pwma,basespeed);analogWrite(pwmb,basespeed); //proceed
		printf(" wf-2 ");
    }
    else{
		analogWrite(pwma,basespeed);analogWrite(pwmb,lowspeed); //bear right
		printf(" wvrt ");
    }
}

void inthezone(){ //if we are between minwdist and maxwdist
	analogWrite(pwma,basespeed);analogWrite(pwmb,basespeed); //proceed
	printf(" wf-3 ");
}

void cruiseAlongWall(){
	if (0!=wdist) oldwdist=wdist; //track the wall distance after the first time
	wdist=pingQ()/2; //get the wall distance in cm
	printf("cw %d\n",wdist);
	if (wdist<minwdist){
		tooclose();
	}else if (wdist>maxwdist){
		toofar();
	}else{
		inthezone();
	}
	//the routines above will have set the motor power levels, now we activate them
	digitalWrite(bin1,HIGH); digitalWrite(bin2,LOW);
	digitalWrite(ain1,HIGH); digitalWrite(ain2,LOW);
	pwmcycleN(15);//forward a bit
}

void main(){
	unsigned int ttl=300; //time to live limit,
	printf("Simpler Panopticon Carbot(L=1,B=255,S=64,min/max=25/30) O-carbotS1.c\n");
	PIN4=0x80;out(4,0x80);
	while(ttl!=00){
		printf("@%d:",ttl);
		digitalWrite(7,LOW);fprox=sharpy(); digitalWrite(7,HIGH);
		printf("<%d ",fprox);
		if (fprox<maxfprox){ // more than 1 ft from barrier
			killdrive();//kill any turn that was going on
			printf("F>\n");
			cruiseAlongWall();//set a course to track the wall
		}else{
			hardleft();
		}
		ttl--; //reduce time to live
	}
	PIN4=0;out(4,0); //kill it all
}
#include <olduino.c>
#include <nstdlib.c>
#include "softpwm.c"
#include "pingBN.c"
//softpwm.c routines for olduino software pulse width management.
//Oct 12 - pwmstep included in pwmcycleN
void analogWrite(unsigned int bit, unsigned int val){
	//printf("analogWrite(%d,%d)\n",bit,val);
	if (bit<2){
		dct[bit]=val>>5; //step down range to 0..7
		//printf("dct[%d]=%cx\n",bit,dct[bit]);
	}
}
void pwmcycleN(unsigned int howmany){ //run howmany*8 steps of the software pwm
	unsigned int step; //toggle table index
	unsigned char * togglep=toggle; //maybe togglep will be in a register
	while(howmany-->0){
		togglep[dct[0]]|=1; //set the end of the duty cycle for bit 0
		togglep[dct[1]]|=2; //set the end of the duty cycle for bit 1
		togglep[0]^=~PIN4; //set up with current state of port4 low bits
		togglep[0]&=0x03; //only the pwm bits are set
		for(step=0;step<8;step++){
			PIN4^=togglep[step];	//toggles the bit off if the duty cycle is over
			out(4,PIN4);
			togglep[step]=0;
		}
	}
}

From → Uncategorized

One Comment

Trackbacks & Pingbacks

  1. What was wrong with Carbot? | olduino

Leave a comment