Sonar to I2c sensor board

This forum is dedicated to software development related to MultiWii.
It is not the right place to submit a setup problem.
Software download
Post Reply
MichalM_sk
Posts: 89
Joined: Wed Jun 15, 2011 5:04 pm
Location: Slovakia

Sonar to I2c sensor board

Post by MichalM_sk »

Hi, I recoded my old I2c protocol code for multiwii (base on Atmega168) to very simple form for easy implementation.

This is my maxbotix sonar to I2c recoded source code with i2c communication.
This code work in all MultiWii versions

Code: Select all

/* ================================================================================================ 
// SONAR I2C SENSOR FOR MULTIWII based on ATMEGA 168
// developed by Michal Maslik(MichalM_sk) in 2011
// recoded for Arduino in 2012
//
// Copyright (C) 2012, Michal Maslik, mobicek@gmail.com
// ONLY FOR NON-COMMERCIAL USAGE
//
// THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE
// ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW.
// ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
//
// BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE
// TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT,
// THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF
// SUCH TERMS AND CONDITIONS.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// ================================================================================================*/

#include <stdio.h>
#include <math.h>
#include <util/delay.h>
#define LED_pin 13

#define   TWIS_ReadBytes      0x60
#define   TWIS_WriteBytes      0xA8
#define TWI_NO_STATE      0xF8 
#define TWI_BUS_ERROR      0x00 

#define I2C_PULLUPS_ENABLE      PORTC |= 1<<4; PORTC |= 1<<5;       //SDA & SCL 
#define I2C_PULLUPS_DISABLE     PORTC &= ~(1<<4); PORTC &= ~(1<<5);

uint8_t TWIS_ResponseType;

struct I2cPart {                       // 2 bytes
  uint8_t NewData;
  uint8_t Alt;
};

union DataBlock {
  struct I2cPart I2cData;
  uint8_t bytes[2];
};

DataBlock dataBlock, dataBlock2;

char DataIsLocked;
static uint8_t newDataFlag = 0;
static uint8_t sonarReaded = 0;

//maxbotix range finder
uint8_t SonarValue = 0;
uint8_t buff;
char first_char;

//I2c routines ///////////////////////////////////////////////////////////////
void TWIS_Init (uint8_t Address, uint32_t Bitrate){

  I2C_PULLUPS_DISABLE;
  TWBR = ((16000000L/Bitrate)-16)/2;
  TWAR = (Address << 1);
  TWCR = (1<<TWEN) | (1<<TWEA) | (1<<TWIE) | (1<<TWSTO);                 
}

void TWIS_Stop (void){
  TWCR = (1<<TWSTO) | (1<<TWINT) | (0<<TWWC) | (1<<TWEN) | (1<<TWEA) | (1<<TWIE);   
}

void TWIS_Write (uint8_t b){   
  TWDR = b;
  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA)|(1<<TWSTO)|(1<<TWSTA);

  while (!(TWCR & (1<<TWINT)));
}

uint8_t   TWIS_ResponseRequired (uint8_t *TWI_ResponseType){
  *TWI_ResponseType = TWSR;
  return TWCR & (1<<TWINT);
}
////////////////////////////////////////////////////////////////////

void lock_out_data()
{
  for (int i=0; i<2; i++)
    dataBlock2.bytes[i] = dataBlock.bytes[i];
  DataIsLocked = true;
}

void setup() {

  sei();  // enable all interupts
  delay(10);   
  TWIS_Init(8,400000L);  // I2c slave address - 8 , 400Khz I2c frequency
  delay(10);

  pinMode(LED_pin, OUTPUT);
  delay(20);

  DataIsLocked = false;
  dataBlock.I2cData.NewData = 0;
  dataBlock.I2cData.Alt = 0;

  Serial.begin(9600);

  digitalWrite(LED_pin, HIGH);
  delay(100);
}

void loop() {

  //read MaxBotix LV sonar sensor
  if(Serial.available() > 0){
    first_char = Serial.read(); // reading char
    //if statement is used to parse the incomming maxbotix serial data
    if(first_char == 'R'){
      lock_out_data();         
      SonarValue = 0;

      buff = Serial.read() - '0';
      SonarValue += buff*100;
      buff = Serial.read() - '0';
      SonarValue += buff*10;
      buff = Serial.read() - '0';
      SonarValue += buff;
      sonarReaded = 1;
    }
    Serial.flush();
  }

  if(sonarReaded == 1){
    newDataFlag++;         
    if(newDataFlag >=60)
      newDataFlag = 1;

    dataBlock.I2cData.Alt = SonarValue;   
    dataBlock.I2cData.NewData = newDataFlag;
    sonarReaded = 0;
    DataIsLocked = false; 
  }   
}

// I2c interrupt ---------------------------------------------------------------------------------------------------

SIGNAL(SIG_2WIRE_SERIAL)
{

  if (TWIS_ResponseRequired (&TWIS_ResponseType)){
    switch (TWIS_ResponseType){

    case TWIS_ReadBytes:
      TWIS_Stop ();
      break;

    case TWIS_WriteBytes:
      for (int i=0;i<2;i++){                   
        if(DataIsLocked)   
          TWIS_Write (dataBlock2.bytes[i]);
        else     
          TWIS_Write (dataBlock.bytes[i]);                                     
      }
      TWIS_Stop ();
      break;

    case TWI_BUS_ERROR:
      TWIS_Stop ();
      break;   
    } 
  }
}



MultiWii Master part

Code: Select all

struct RfI2cPart {
    uint8_t NewData;
    uint8_t Alt;           //in inches
};

union RfDataUnion {
    struct RfI2cPart RfI2cData;
    uint8_t bytes[2];
} rfBlock;

//I2C comunication speed changed to 400Khz
TWBR = ((16000000L / 400000L) - 16) / 2;
i2c_rep_start((8<<1) + 1);                     
 
rfBlock.bytes[0]= i2c_readAck();
rfBlock.bytes[1]= i2c_readNak();


User avatar
Bledi
Posts: 187
Joined: Sat Sep 10, 2011 6:36 pm

Re: Sonar to I2c sensor board

Post by Bledi »

EXCELLENT !!!!!!!!!!! Thanks a lot

Post Reply