Ultrasonic and bluetooth.

I got my Hexy for Christmas. I put it together today. I have loaded. the new firmware. I have connected to it to pomoco (crapper name to type by the way). I haven’t found instructions for the Ping( the ultra sonic sensor.) Also is there a “wander around looking at stuff and avoiding things” Algorithm out there some where. Something simple and subsumtive?

For ultrasonic the forum tell :

Replace

#include "WProgram.h" by #include "Arduino.h" in ultrasonic.h and cpp

Complete firmware with changes (D command return Distance in CM) :

[code]#include “TimerOne.h”
#include “SPI.h”

//////////////////////////////
#include “Ultrasonic.h”

#define TRIGGER_PIN 17
#define ECHO_PIN 11

Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);

/////////////////////

#define STATUS_LED 7

#define SERVOS 32
#define MAX_TIMINGS 36

#define ON10 PORTB |= (1<<6) // turn on pin 10
#define OFF10 PORTB &= ~(1<<6) // turn off pin 10

#define GROUPS 4
#define SERVOS_PER_GROUP 8

uint16_t group_offsets[4] = {0,251,502,753};
uint8_t group_latches[4] = {5,6,7,4};

uint8_t pin_2_num[8] = {0x08,0x04,0x02,0x01, 0x80,0x40,0x20,0x10};

uint8_t servo_positions[SERVOS];

uint16_t servo_timings[MAX_TIMINGS];
uint8_t shift_output[MAX_TIMINGS];
uint8_t shift_latch[MAX_TIMINGS];

uint16_t timer;
uint8_t counter = 0;
uint8_t pwm_active = 1;

uint8_t update_reg_flag = 0;

///////////////////////
int printDistanceCM()
{
float duration, cm;
digitalWrite(TRIGGER_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIGGER_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER_PIN, LOW);
duration = pulseIn(ECHO_PIN, HIGH,3000000);
cm = duration / 29.0 / 2.0;

//Serial.print("CM: ");
//Serial.println(cm);
return cm;
}
/////////////////////////////////

void setup() {
//setup pin modes
DDRF |= 0xF0; // sets pins F7 to F4 as outputs
DDRB = 0xFF; // sets pins B0 to B7 as outputs
pinMode(STATUS_LED,OUTPUT);
//setup PC serial port
Serial.begin(9600);
Serial1.begin(9600);
//delay(100); // delay to establish the usb connection. using the arduino while-serial command doesn’t
// let it boot properly when there’s no USB conenction.

// setup SPI port
SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV2);

//start the servo-timing timer and associated interrupt
Timer1.initialize(10); // initialize timer1, and set a period of 10 uS
Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt

for(uint8_t i=0; i<MAX_TIMINGS; i++){
servo_timings[i] = 0;
shift_output[i] = 0xFF;
shift_latch[i] = 0xFF;
}
for(uint8_t i=0; i<SERVOS; i++){
servo_positions[i] = 0;
}
update_registers();
}

long unsigned int us_counter = 0;
long unsigned int startTime = 0;
long unsigned int currentTime = 0;
long unsigned int last_update = 0;

long unsigned int micros_new(){
return us_counter;
}

long unsigned int millis_new(){
return us_counter/1000;
}

void delay_new(long unsigned int delay_time){
startTime = millis_new();
currentTime = millis_new() - startTime;
while(currentTime < delay_time){
delayMicroseconds(10);
currentTime = millis_new() - startTime;
}
}

void callback(){
cli();
if(timer == servo_timings[counter]){
SPDR = shift_output[counter]; // push the byte to be loaded to the SPI register
//asm(“nop\n\tnop\n\tnop\n\t”); // pause to wait for the spi register to complete its shift out
while(!(SPSR & (1<<SPIF))); //wait till the register completes
PORTF &= ~(shift_latch[counter]); // clock the shift register latch pin low, setting the register
PORTF |= shift_latch[counter]; // clock the shift register latch pin high, ready to be set low next time
counter++;
}

timer++;
us_counter += 10;
if(timer == 1010){
update_reg_flag=1;
}

if(timer == 2000){
update_reg_flag=0;
timer=0;
counter=0;
}
sei();
}

void update_registers(){
while( update_reg_flag != 1){
//asm(“nop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\t”);
delayMicroseconds(10);
}
for(uint8_t i=0; i<MAX_TIMINGS; i++){ // clear existing registers, so they can be cleanly written
servo_timings[i] = 0;
shift_output[i] = 0xFF;
shift_latch[i] = 0xFF;
}

uint8_t current_timing=0;
uint8_t group=0;
uint8_t group_active_flag=0;
uint8_t servo_num=0;

uint8_t group_on_time = 0;

uint16_t servo_time=0;

uint8_t group_active_servo_count = 0;

// insert active servos into timing array
for(uint8_t group=0; group<GROUPS; group++){ // go through all groups
group_active_flag = 0;

// ---- arrange the servos in the group from lowest to highest timing length -----

// see how many active servos in the group there are
// make a temp copy of postions to organize with
group_active_servo_count = 0;
uint16_t servo_positions_copy[SERVOS_PER_GROUP] = {};
for(uint8_t servo=0; servo<SERVOS_PER_GROUP; servo++){
  if(servo_positions[SERVOS_PER_GROUP*group+servo] != 0){
    group_active_servo_count++;
  }
  servo_num = servo+SERVOS_PER_GROUP*group;
  servo_positions_copy[servo] = servo_positions[servo_num];
}

// sort them into a new order
uint8_t group_timing_order[SERVOS_PER_GROUP] = {0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF};
uint8_t low_count=0;
for(uint8_t i=0; i<group_active_servo_count; i++){
  uint8_t lowest_position=251;
  for(uint8_t j=0; j<SERVOS_PER_GROUP; j++){
    if(servo_positions_copy[j] != 0){
      if(servo_positions_copy[j] < lowest_position){
        lowest_position = servo_positions_copy[j];
        group_timing_order[low_count] = j;
      }
    }
  }
  servo_positions_copy[group_timing_order[low_count]]=0;
  low_count++;
}


// ---- go through the active servos and insert timings---

// turn on all needed servos in the group at the beginning of their pulse
if(group_active_servo_count > 0){
  group_on_time = current_timing;
  servo_timings[group_on_time] = group_offsets[group];
  shift_output[group_on_time] = 0x00; 
  shift_latch[group_on_time] = (1<<group_latches[group]);

  // turn on all the servos that will be turned on
  for(uint8_t i=0; i<group_active_servo_count; i++){
    shift_output[group_on_time] |= pin_2_num[group_timing_order[i]];
  }
  current_timing++;  
}

for(uint8_t i=0; i<group_active_servo_count; i++){ // go through all active servos in the group
  uint8_t servo = group_timing_order[i];
  servo_num = servo+SERVOS_PER_GROUP*group;
  servo_time = group_offsets[group] + servo_positions[servo_num];    // calculate the servo's time off
  shift_output[group_on_time] |= pin_2_num[servo]; // turn on the servo at the group's turn-on time

  // go over existing timings for this group, make sure there's not already one with this timing there 
  uint8_t original = 1;
  for(uint8_t j=1; j<group_active_servo_count; j++){
    if( servo_timings[j+group_on_time] == servo_time){
      shift_output[j+group_on_time] &= (~(pin_2_num[servo])); // turn off the servo at this timing
      original=0;
    }
  }    
 // create a timing if there's no existing timing
 if(original == 1){
    servo_timings[current_timing] = servo_time;
    shift_output[current_timing] = shift_output[current_timing-1] & (~(pin_2_num[servo])); // turn off the servo at this timing
    shift_latch[current_timing] = (1<<group_latches[group]);
    current_timing++;
 }
}
update_reg_flag=2;

}

// show the final register values
/*
for(uint8_t i=0; i<MAX_TIMINGS; i++){ // clear existing registers, so they can be cleanly written
Serial.print(i);
Serial.print(":\t");
Serial.print(servo_timings[i]);
Serial.print(",\t");
Serial.print(shift_output[i],HEX);
Serial.print(",\t");
Serial.println(shift_latch[i],HEX);
}
*/
}

boolean debug = false;
boolean testMode = false;
boolean servoCounting = false;
boolean posCounting = false;

byte numString[6];
int powers[] = {1,10,100,1000};

byte numCount = 0;
unsigned short total = 0;
short inServo = -1;
short inPos = -1;

void loop() {

digitalWrite(STATUS_LED, HIGH);
delay_new(500);
digitalWrite(STATUS_LED, LOW);
delay_new(500);

for(int i=0; i<32; i++){
changeServo(i,0);
}

changeServo(0,1500);
changeServo(1,1500);
changeServo(2,1500);
changeServo(3,1500);

delay_new(100);

while(true){
TIMSK0 &= ~(_BV(TOIE0)); // disables the arduino delay function, but also
// all but eliminates servo jitter
TIMSK2 &= ~(_BV(TOIE2)); // disable the arduino tone function, but also
// also helps eliminate some jitter
TIMSK3 &= ~(_BV(TOIE3)); // for good measure
TIMSK4 &= ~(_BV(TOIE4)); // for good measure
if(update_reg_flag == 1){
update_registers();
}
else{
if(Serial.available()) {
char inChar = (char)Serial.read();
switch(inChar){
case ‘#’:
ON10;
servoCounting = true;
numCount = 0;
inServo = -1;
inPos = -1;
//Serial.println("# received ");
break;
case ‘P’:
if(servoCounting){
inServo = tallyCount();
servoCounting = false;
}
posCounting = true;
numCount = 0;
//Serial.println("P received " + inServo);
break;
case ‘\r’:
case ‘\n’:
OFF10;
if(posCounting){
inPos = tallyCount();
posCounting = false;
}
if((inServo >=0)&&(inServo <=31)&&(((inPos >= 500)&&(inPos <= 2500))||(inPos == -1))){
changeServo(inServo,inPos);
if((inServo == 25)||(inServo == 26)){
Serial.println(inServo); // only for debugging
}

          inServo = -1;
          inPos = -1;
        }
        numCount = 0;
        break;
      case 'V':
        Serial.println("SERVOTOR32_v1.7");
        break;
      case 'C':
        for(int i=0; i<32; i++){
          Serial.println(i);
        }
        Serial.println("All Centered");
        break;
      case 'K':
        for(int i=0; i<32; i++){
          changeServo(i,0);
        }
        Serial.println("All Turned Off");
        break;
      case 'L':
        if(servoCounting){
          inServo = tallyCount();
          servoCounting = false;
        }
        changeServo(inServo, -1);
        //Serial.println("L received");
        break;
        case 'D': //ultrasonic
        //printDistanceCM(); //ultrasonic
        Serial.println(printDistanceCM());
        break;
      default:
        if((inChar > 47)&&(inChar < 58)){
          if(numCount<4){
            numString[numCount] = inChar-48;
            numCount++;
          }
        }
        break;
    } 
  }
  if(Serial1.available()){
    char inChar = (char)Serial1.read();
    switch(inChar){
      case '#':
        servoCounting = true;
        numCount = 0;
        inServo = -1;
        inPos = -1;
        break;
      case 'P':
        if(servoCounting){
          inServo = tallyCount();
          servoCounting = false;
        }
        posCounting =  true;
        numCount = 0;
        break; 
      case '\r':
      case '\n':
        if(posCounting){
          inPos = tallyCount();
          posCounting = false;
        }
        if((inServo >=0)&&(inServo <=31)&&(((inPos >= 500)&&(inPos <= 2500))||(inPos == -1))){
          changeServo(inServo,inPos);
          inServo = -1;
          inPos = -1;
        }
        numCount = 0;
        break;
      case 'V':
        Serial1.println("SERVOTOR32_v1.7");
        break;
      case 'C':
        for(int i=0; i<32; i++){
          changeServo(i,1500);
        }
        Serial1.println("All Centered");
        break;
      case 'K':
        for(int i=0; i<32; i++){
          changeServo(i,0);
        }
        Serial1.println("All Turned Off");
        break;
      case 'L':
        if(servoCounting){
          inServo = tallyCount();
          servoCounting = false;
        }
        changeServo(inServo, -1);
        break;
        case 'D': //ultrasonic
        //printDistanceCM(); //ultrasonic
        Serial.println(printDistanceCM());
        break;
      default:
        if((inChar > 47)&&(inChar < 58)){
          if(numCount<4){
            numString[numCount] = inChar-48;
            numCount++;
          }
        }
        break;
    } 
  }
}  

}
}

void changeServo(byte servo, short pos){
servo_positions[servo] = pos/10;
}

short tallyCount(){
total=0;
for(int i=0; i<numCount; i++){
total += powers[i]*numString[(numCount-1)-i];
}
if(numCount == 0){
total = -1;
}
return total;
}
[/code]

Don’t work for me at that time.
I think the pin 17 & 11 are not true.

Total robotics/arduino newbie here with a really broad question on the ping sensor:

I have no idea how the ping sensor works or what I’ll need to do to get it working ._.

Do I upload the ping code to Hex like I did with the firmware? How do I test the sensor to make sure it’s working properly? Does the sensor output print somewhere?

EDIT 1 - progress so far

I added the ultrasonic library by following the instructions above. I’ll type them out here in the order I did them.

  1. Downloaded the ultrasonic library and placed it in the arduino library folder. Library is here: http://jaktek.com/wp-content/uploads/2011/12/Ultrasonic.zip
  2. Replaced the #include “WProgram.h” line in both the ultrasonic.h and the ultrasonic.cpp files of the library with #include “Arduino.h”
  3. Imported the library to the Servotor sketch. Follow this guide for more.
  4. Uploaded the modified Servotor sketch
  5. Uploaded the test code sketch to Hexy.
  6. Tested the test code sketch in Serial Monitor - it produces an output.
  7. Finally resolved the sensor issue by plugging it in right :blush: