/** * sonar.osc * This shows how to use the OOPic with a hacked out Polaroid * SONAR unit like I show on my web pages. It requires 3.0.4 * compiler. * PWR = I/O 27 * INIT= I/O 28 * ECHO= I/O 29 */ //Timing constants Final ms10 = 12500; //SONAR values oWord sEnd = new oWord; oWord rslt = new oWord; oDio1 PWR = New oDio1; oDio1 INIT = New oDio1; oDio1 ECHO = New oDio1; oGate doTimer = New oGate(2); oTimer timer = New oTimer; //serial LCD values used oSerial LCD = new oSerial; oNibble i = New oNibble; oByte mTemp1 = new oByte; oBit bTemp = new oBit; oWord wTemp = new oWord; Sub void main(void) { LCD.Baud = cv9600; //9600 baud LCD.Mode = 0; //asynchronous LCD.Operate = cvTrue; //turn it on sendCmd(12); sendCmd(2); /* * Sound takes about 148us to travel 1 inch out and * back. Each tic of the timer (div 8) is 1.6us * therefore tics*1.6/148 = distance away in inches. * or 148/1.6 = 92.5, so tics/93 = inches distance. */ LCD.String = "SONAR Tests."; printf; OOPic.delay = 200; setSonar; do { rslt = doSonar; printWord(rslt); LCD.String = " = "; printWord(rslt/93); LCD.String = " in"; printf; OOPic.delay = 50; } while (1 == 1); } Sub void setSonar(void) { timer.PreScale = 3; PWR.IOLine = 27; PWR.Direction = cvOutput; INIT.IOLine = 28; INIT.Direction = cvOutput; ECHO.IOLine = 29; ECHO.Direction = cvInput; INIT.Value = cvLow; //reset INIT PWR.Value = cvHigh; doTimer.Input1.Link(INIT.NonZero); doTimer.InvertIn1 = cvTrue; doTimer.Input2.Link(ECHO.Value); doTimer.InvertOut = cvTrue; doTimer.Output.Link(timer.Operate); doTimer.Operate = cvTrue; //First pull PWR low then wait 5-10ms //Now set INIT = 1, this feeds timer gate in 1 //which starts the timer because ECHO is low //When ECHO goes high this disables the gate //output which stops the timer. } Function oWord doSonar() { // Take SONAR reading PWR.Value = cvLow; //turn power on //OOPic.delay=1; timer.Value = 0; INIT.Value = cvHigh; do {} while (ECHO == 0); //wait until done sEnd = timer.Value; INIT.Value = cvLow; PWR.Value = cvHigh; //turn power off return sEnd; } Sub void sendCmd(oByte d) { //send commands out LCD.Value = 16; //LCD command LCD.Value = d; } Sub void printf(void) { //Send a character LCD.Value = 13; LCD.Value = 10; } Sub void printWord(oWord wt) { //Print out a word, byte, nibble or bit value bTemp = 0; mTemp1 = 0; for (wTemp = 1;wTemp < 20000;wTemp*=10) { mTemp1 = wt/(10000/wTemp); if ((mTemp1 > 0) | (bTemp == 1) | (wTemp==10000)){ wt = wt - mTemp1 * (10000/wTemp); bTemp = 1; LCD.Value = mTemp1 + 48; } } }