Skip to content

Embedded Software for the Beacon

The software for the beacon is a compilation of the different assignment weeks. You can find below the link to the different week referring to the function used :

As you can see, I took profit of the assignments to test and write several functions that help me on my final project. But, when it was time to combine all of the function, I need to re-write some of the function to make it work correctly.

So this page will resume all of the new and old functions for the final project.

Communication

Basically, the communication part were really well covered by my work on week14 and week16. So, if you need more informations about how I develop those functions, please go on the related assignment pages.

Sending values ( position of the opponent )

The core of the code is the sending function. I need to send the following informations from my board to my application :

  • byte - a char to signify the begin of the communication. It will be ‘b’
  • unsigned integer - Distance of the robot
  • unsigned integer - Angle of the robot
  • byte - a char to signify the end of the communication. It will be ‘\n’

As I cannot send int value with my serial communication, I will parse each unsigned integers into two bytes.

To do that I will use the following to parse an integer into two bytes :

byte1=distance >> 8;
byte2=distance & 255;

And then implement it on the ATTtiny sending side :

void sendPosition(int distance,int angle)
{
  digitalWrite(led,HIGH);
  sendBuffer[0]='b';              // Byte that begin the communication
    sendBuffer[1]=distance >> 8;
    sendBuffer[2]=distance & 255;
    sendBuffer[3]=angle >> 8;
    sendBuffer[4]=angle & 255;
  sendBuffer[5]='\n';             // Byte that end the communication

  for(int i=0;i<=5;i++)
    {
        Serial.write(sendBuffer[i]);
    }
  digitalWrite(led,LOW);
}

Receiving datas ( parameters )

I also need to receive value from the sender. To do that I created a function that update parameters into the receiver. The idea is that this function can be easily modified in the futur if a need to update multiple paramaters, as long as the parameters are byte and not int.

void updateParameters()
{
  if (Serial.available()>0)
  {
    byte c = Serial.read();
    analogWrite(motor,c);
  }
}

The updateParameters() function will be call the most frequently as we can into the code so we can detect quickly when a message is received.

Speed regulation

For the speed regulation of the motor, I use the magnet and the hall sensor. The idea is to measure the time between two reading and to determine the speed. To do the speed regualtion, I did a simple function. It has to be called the more often we can.

bool readHall()
{
  bool hallSensorState = digitalRead(hallSensor);
  long temp = 0;
  digitalWrite(led,!hallSensorState);
  // If detect a fallen edge
  if(!hallSensorState && previousHallState)
  {
    if(initTurnTime!=0)
    {
      temp = millis()-initTurnTime;
    }
    // check if there is no rebound on the sensor
    if (temp > 100)
    {
      turnTime = temp ;
      if (turnTime>timeMotorTurn)
      {
        if (actualSpeed<=250) actualSpeed+=5 ;
      }
      else if (turnTime<timeMotorTurn)
      {
        if (actualSpeed>=5) actualSpeed-=5 ;
      }
      analogWrite(motor,actualSpeed);
    }
    initTurnTime = millis();
  }
  previousHallState = hallSensorState ;
  return hallSensorState;
}

It work with the detection of the rising and falling edge of the hall sensor. The led is used to monitor the sensor state. I use the millis() function to determine the time between two reading. Like this I have a non blocking function.

Distance and position detection

This part of the programm is very similar to the hall sensor reading. But, instead of calculate the time between two readings, we will calculate :

  • The time between the hallsensor reading and the distance sensor to know the orientation of the opponent
  • The time between a rising and a falling edge of the sensor output

For this last part, we measure the time when the reflective beacon is detected and we determine the distance with this measurement. But it need a little bit of calibration.

bool readSensor()
{
  bool sensorState = digitalRead(distanceSensor);
  digitalWrite(led,sensorState);

  if(sensorState && !previousSensorState)
  {
    // If detect a rising edge
    initObjectTime = millis();

  }
  else if (!sensorState && previousSensorState)
  {
    // If detect a fallen edge
    if(initObjectTime!=0) objectTime = millis()-initObjectTime;

    distanceMeasured = (objectTime - 403 )/(-1.2) ;
    long temp = initObjectTime - initTurnTime ;
    temp = temp * 360 ;
    angleMeasured = temp / turnTime ;

    if (angleMeasured > 68 || angleMeasured < 48) sendPosition(distanceMeasured, angleMeasured);
  }
  previousSensorState = sensorState ;
  return sensorState;
}

Conclusion

The code is available here. The main function are below and the rest of the code is testing function and declarations. Now I need to test and calibrate the sensor.