Электронный компас — различия между версиями

Материал из roboforum.ru Wiki
Перейти к: навигация, поиск
м
(Регистры)
Строка 155: Строка 155:
 
*Reg 15 = 0xF2
 
*Reg 15 = 0xF2
 
Это можно сделать за одну транзакцию записав 4 байта в Reg 12, указатель смещается автоматически
 
Это можно сделать за одну транзакцию записав 4 байта в Reg 12, указатель смещается автоматически
 +
 +
 +
=== Пример на Bascom-AVR ===
 +
 +
<source lang="vb">
 +
'-------------------------------------------------------------------------------
 +
'name                    : MB_CMPS03.bas
 +
'copyright                : (c) 2008, Konstantin Kostyuk
 +
'purpose                  : read data from CMPS03 - digital compass for I2C
 +
'MCU                      : Mega32
 +
'device                  : MiniBot - Russian National Class
 +
'commercial addon needed  : no
 +
'-------------------------------------------------------------------------------
 +
$prog &HFF , &HE4 , &HD9 , &H00
 +
$regfile = "m32def.dat"
 +
$crystal = 8000000
 +
$baud = 2400
 +
$framesize = 42
 +
$swstack = 32
 +
$hwstack = 32
 +
'$sim
 +
'-------------------------------------------------------------------------------
 +
' Hardvare
 +
'
 +
' PC0 - I2c SLC
 +
' PC1 - I2c SDA
 +
Config Scl = Portc.0
 +
Config Sda = Portc.1
 +
Config Pinc.4 = Output : Led1_red Alias Portc.4
 +
'-------------------------------------------------------------------------------
 +
'Constants
 +
Const Switch_on = 1
 +
Const Switch_off = 0
 +
Const Cmps_addres = &HC0
 +
'-------------------------------------------------------------------------------
 +
'Declarations
 +
Declare Function Mb_cmps_measuring(byval I2c_address As Byte) As Word
 +
Declare Function Mb_cmps_firmware(byval I2c_address As Byte) As Byte
 +
Declare Function Mb_cmps_newaddress(byval Current As Byte , Byval New As Byte) As Byte
 +
Declare Sub Mb_cmps_reset(byval I2c_address As Byte)
 +
'-------------------------------------------------------------------------------
 +
'Variables
 +
Dim Measuring As Word
 +
Dim Angle As Single
 +
Dim Bcount As Byte
 +
'-------------------------------------------------------------------------------
 +
'Start Execution
 +
 +
  Waitms 500
 +
  I2cinit
 +
  Print "MiniBot CMPS03 Compass Test"
 +
  Print "CMPS03 Firmware Version: " ; Mb_cmps_firmware(cmps_addres)
 +
 +
 +
  Bcount = 0
 +
  Do
 +
    Led1_red = Switch_on
 +
    Waitms 500
 +
 +
    Measuring = Mb_cmps_measuring(Cmps_addres)
 +
    Print Bcount
 +
    Print "Measuring in 0,1 Angle: " ; Measuring
 +
    Angle = Measuring / 10
 +
    Print "Measuring transfered to Angle: " ; Angle
 +
    Incr Bcount
 +
 +
    Led1_red = Switch_off
 +
    Waitms 500
 +
  Loop
 +
 +
End
 +
'End execution
 +
'-------------------------------------------------------------------------------
 +
 +
Function Mb_cmps_measuring(ByVal I2c_address as Byte) As Word
 +
Local Lo_byte As Byte
 +
Local Hi_byte As Byte
 +
Local Cmps_slave As Byte
 +
Local Cmps_slave_read As Byte
 +
 +
  Cmps_slave = I2c_address
 +
  Cmps_slave_read = Cmps_slave + 1
 +
  Lo_byte = 0
 +
  Hi_byte = 0
 +
 +
  I2cstart
 +
  I2cwbyte Cmps_slave
 +
  I2cwbyte 2
 +
  I2cstop
 +
 +
  I2cstart
 +
  I2cwbyte Cmps_slave_read
 +
  I2crbyte Hi_byte , Ack
 +
  I2crbyte Lo_byte , Nack
 +
  I2cstop
 +
 +
  Mb_cmps_measuring = Makeint(lo_byte , Hi_byte)
 +
End Function
 +
 +
 +
Function Mb_cmps_firmware(ByVal I2c_address as Byte) As Byte
 +
Local Firmware As Byte
 +
Local Cmps_slave As Byte
 +
Local Cmps_slave_read As Byte
 +
 +
  Cmps_slave = I2c_address
 +
  Cmps_slave_read = Cmps_slave + 1
 +
  Firmware = 0
 +
 +
  I2cstart
 +
  I2cwbyte Cmps_slave
 +
  I2cwbyte 0
 +
  I2cstop
 +
 +
  I2cstart
 +
  I2cwbyte Cmps_slave_read
 +
  I2crbyte Firmware , Nack
 +
  I2cstop
 +
 +
  Mb_cmps_firmware = Firmware
 +
End Function
 +
 +
Sub Mb_cmps_reset(byval I2c_address As Byte)
 +
Local Firmware As Byte
 +
Local Cmps_slave As Byte
 +
Local Cmps_slave_read As Byte
 +
 +
  Cmps_slave = I2c_address
 +
  Cmps_slave_read = Cmps_slave + 1
 +
  Firmware = 0
 +
 +
  I2cstart
 +
  I2cwbyte Cmps_slave
 +
  I2cwbyte 12
 +
  I2cwbyte &H55
 +
  I2cwbyte &H5A
 +
  I2cwbyte &HA5
 +
  I2cwbyte &HF2
 +
  I2cstop
 +
 +
 +
End Sub
 +
 +
Function Mb_cmps_newaddress(byval Current As Byte , Byval New As Byte) As Byte
 +
Local Firmware As Byte
 +
Local Cmps_slave As Byte
 +
Local Cmps_slave_read As Byte
 +
 +
  Cmps_slave = Current
 +
  Cmps_slave_read = Cmps_slave + 1
 +
  Firmware = 0
 +
 +
  I2cstart
 +
  I2cwbyte Cmps_slave
 +
  I2cwbyte 12
 +
  I2cwbyte &HA0
 +
  I2cwbyte &HAA
 +
  I2cwbyte &HA5
 +
  I2cwbyte New
 +
  I2cstop
 +
 +
End Function
 +
</source>

Версия 14:09, 25 декабря 2008

Электронный компас CMPS03 производства Devantech Ltd.

Этот документ для CMPS03 версии Rev14 и позднее.

Отличить версии можно по отсутствию 8МГц керамического кварца в центре платы.

  • Rev14 Март 2008
  • Rev15 Апрель 2008


Статья является вольным переводом документов:

Описание

Модуль CMPS03 был специально разработан для применения в роботах как вспомогательное средство навигации. Целью ставилось получить устройство которое выдает уникальное числовое значение описывающее направление фронтальной поверхности робота. В компасе используются три сенсора магнитного поля Philips KMZ51, чувствительности которых достаточно для определения магнитного поля Земли. Компас позволяет определить направление, используя горизонтальную направляющую магнитного поля Земли. Компания предоставляет примеры использования CMPS03 с основными типами МК.

Подключение

Cmps3pin2.jpg

  • Pin 1, +5v. Модулю компаса необходимо питание 5Вольт, потребление 25 мАмпер.
  • Pins 2,3 являются линиями SCL и SDA для I2C интерфейса. Применяются для чтения данных о направлении. Если I2C интерфейс не используется, на выходы подается высокий уровень (+5 вольт) через пару резисторов примерно по 47 кОм.
  • Pin 4 выход PWM(pulse width modulated) сигнала. Данные представляются PWM в аналоговом виде. Импульсы от 1mS (0°) до 36.99mS (359.9°) – другими словами, 100uS/° со смещением +1mS. Ширина промежутка между импульсами 65mS, то есть период импульсов 65mS + время импульса = 66mS-102mS. Импульс формируется 16 битным таймером процессора, что позволяет достичь разрешения в 1uS
  • Pin 5 используется при калибровке модуля. Если хотите подключите LED между выходом и +5v через резистор на 390 Ом.
  • Pin 6 используется для калибровки. Процесс калибровки описан в следующей главе.
  • Pins 7,8 на текущий момент не используются. Они оснащены подтягивающими резисторами.
  • Pin 9 0 вольт = ground = земля.

Колибровка

Калибровку рекомендуется делать при каждом включении питания (реально если модуль, пока было выключено питание, изменил свое местоположение на север или юг более чем на пару - тройку сотен километров). Данные сохраняются в EEPROM на PIC16F872. Модуль калибруется на производстве со склонением 67 градусов(Великобритания), если ваше склонение близко то можно и не калибровать.

После калибровки при следующей ориентации модуля на Север будет выдаватся значение 0.

North.gifПоложение на Север = на выходе 0

I2C Method

Для калибрации используем I2C шину, необходимо записывать 255 (0xff) в Регистр 15 для каждого из основных направлений Север, Восток, Юг и Запад. Направления могут задаваться в любой последовательности, но все четыре направления необходимо установить. Пример:

  1. Поместить компас на плоскость, позиционировать на Север(см. рис. выше). Записать 255 в регистр 15
  2. Поместить компас на плоскость, позиционировать на Восток. Записать 255 в регистр 15
  3. Поместить компас на плоскость, позиционировать на Юг. Записать 255 в регистр 15
  4. Поместить компас на плоскость, позиционировать на Запад. Записать 255 в регистр 15


Pin Method

Pin 6 используется для калибровки. Вход(pin 6) имеет подтягивающий резистор и может быть отключен после калибровки. Для установки направления нужно что бы на входе был постоянно высокий уровень, и в момент установки правильного направления подать низкий уровень затем вернуть высокий. Простейший путь нажать кнопку. Направления могут задаваться в любой последовательности, но все четыре направления необходимо установить. Пример:

  1. Поместить компас на плоскость, позиционировать на Север(см. рис. выше). Нажать - Отпустить кнопку
  2. Поместить компас на плоскость, позиционировать на Восток. Нажать - Отпустить кнопку
  3. Поместить компас на плоскость, позиционировать на Юг. Нажать - Отпустить кнопку
  4. Поместить компас на плоскость, позиционировать на Запад. Нажать - Отпустить кнопку


Важно

ВНИМАНИЕ - Во время калибровки компас должен находиться на плоской горизонтальной поверхности параллельно поверхности земли, элементами вверх. Рядом(10-12 дюймов, примерно 25-30 см) не должно находиться металлических - а особенно магнитных объектов.

Калибровка обязательно должна быть выполнена в четыре шага, по одному на каждую сторону света.

  • Предыдущие версии компаса позволяли повторить каждый шаг столько раз сколько надо. В память запоминались последние измерения для каждой стороны света.
  • В Rev 14 алгоритм изменен. Первый шаг(низкий уровень на Pin 6 или запись 255 в Register 15) инициирует внутренний механизм сбора данных и только по окончанию Четвертого шага калибровочные данные сохраняются в EEPROM. Когда вы выполняете Первый шаг на Pin 5 выставляется низкий уровень, после Четвертого шага возвращается в высокий уровень. Поэтому на Pin 5 ставится светодиод через резистор 390ом, который показывает что модуль находится в состоянии калибрации.

Применение

I2C interface

CMPS03 является Slave устройством на I2C шине

  • Master, начиная общение по шине - посылает стартовую последовательность.
  • Это сигнал для всех Slave устройств подключенных к шине, что начался сеанс передачи данных.
  • Master отсылает по шине адрес устройства с которым инициируется сеанс связи.
  • Slave устройств который узнал свой адрес продолжает общение с Master.

Пример записи данных для CMPS03.

У CMPS03 I2C адрес по умолчанию 0xС0, установить модуль на север и для калибровки модуля нужно записать 255 в Register 15.

  1. Послать стартовую последовательность
  2. Послать 0xC0 - I2C адрес CMPS03 с нулевым битом чтения/записи
  3. Послать 0x0F (Внутренний адрес регистра команд)
  4. Послать 0xFF (команда, калибровки)
  5. Повернуть на Запад
  6. Послать 0xFF (команда, калибровки)
  7. Повернуть на Юг
  8. Послать 0xFF (команда, калибровки)
  9. Повернуть на Восток
  10. Послать 0xFF (команда, калибровки)
  11. Послать завершающую последовательность.


Пример чтения данных азимута в виде байта из CMPS03.

  • Master - посылает стартовую последовательность.
  • Master - отсылает по шине адрес устройства с которым инициируется сеанс связи.
  • Master - сообщает Slave - из какого его внутреннего регистра он хочет читать.
  • Master - посылает вторую стартовую последовательность и снова адрес I2C - на этот раз единичным битом чтения/записи .
  • Master - Мастер читает столько байт сколько ему хочется и заканчивает сеанс завершающей последовательностью.
  1. Послать стартовую последовательность
  2. Послать 0xC0 - I2C адрес CMPS03 с нулевым битом чтения/записи
  3. Послать 0x01 (Внутренний адрес регистра азимута)
  4. Послать стартовую последовательность снова (повторный старт)
  5. Послать 0xC1 - I2C адрес CMPS03 с единичным битом чтения/записи
  6. Читать байт данных от CMPS03
  7. Послать завершающую последовательность


Регистры

Register Описание
0 Версия ПО. Нужно Rev 14 или больше.
1 Азимут компаса как байт (0-255 на 360 градусов).
2,3 Азимут компаса как слово (0-3599 соответствующие 0-359.9 градусам).
12 Код разблакировки 1 - используется для смены I2C адреса и возврата заводских настроек.
13 Код разблакировки 2 - используется для смены I2C адреса и возврата заводских настроек.
14 Код разблакировки 3 - используется для смены I2C адреса и возврата заводских настроек.
15 Командный регистр.

Изменения I2C адреса (по умолчанию 0xC0)

Начиная с Rev14 стало возможно назначения адреса модулю отличного от 0xC0. Можно назначить один из следующих 8ми адресов - 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC or 0xCE. Записываем Код разблакировки в регистры 12,13 и 14 а новый адрес в регистр 15.

  • Reg 12 = 0xA0
  • Reg 13 = 0xAA
  • Reg 14 = 0xA5
  • Reg 15 = новый адрес(0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC or 0xCE)

Новый адрес вступает в силу немедленно!!!


Востановление Заводской Калибровки.

Начиная с Rev14 стало возможно востановление заводской калибровки. Записываем Код разблакировки в регистры 12,13 и 14 а и команду востановления в регистр 15.

  • Reg 12 = 0x55
  • Reg 13 = 0x5A
  • Reg 14 = 0xA5
  • Reg 15 = 0xF2

Это можно сделать за одну транзакцию записав 4 байта в Reg 12, указатель смещается автоматически


Пример на Bascom-AVR

<source lang="vb"> '------------------------------------------------------------------------------- 'name  : MB_CMPS03.bas 'copyright  : (c) 2008, Konstantin Kostyuk 'purpose  : read data from CMPS03 - digital compass for I2C 'MCU  : Mega32 'device  : MiniBot - Russian National Class 'commercial addon needed  : no '------------------------------------------------------------------------------- $prog &HFF , &HE4 , &HD9 , &H00 $regfile = "m32def.dat" $crystal = 8000000 $baud = 2400 $framesize = 42 $swstack = 32 $hwstack = 32 '$sim '------------------------------------------------------------------------------- ' Hardvare ' ' PC0 - I2c SLC ' PC1 - I2c SDA Config Scl = Portc.0 Config Sda = Portc.1 Config Pinc.4 = Output : Led1_red Alias Portc.4 '------------------------------------------------------------------------------- 'Constants Const Switch_on = 1 Const Switch_off = 0 Const Cmps_addres = &HC0 '------------------------------------------------------------------------------- 'Declarations Declare Function Mb_cmps_measuring(byval I2c_address As Byte) As Word Declare Function Mb_cmps_firmware(byval I2c_address As Byte) As Byte Declare Function Mb_cmps_newaddress(byval Current As Byte , Byval New As Byte) As Byte Declare Sub Mb_cmps_reset(byval I2c_address As Byte) '------------------------------------------------------------------------------- 'Variables Dim Measuring As Word Dim Angle As Single Dim Bcount As Byte '------------------------------------------------------------------------------- 'Start Execution

  Waitms 500
  I2cinit
  Print "MiniBot CMPS03 Compass Test"
  Print "CMPS03 Firmware Version: " ; Mb_cmps_firmware(cmps_addres)


  Bcount = 0
  Do
    Led1_red = Switch_on
    Waitms 500
    Measuring = Mb_cmps_measuring(Cmps_addres)
    Print Bcount
    Print "Measuring in 0,1 Angle: " ; Measuring
    Angle = Measuring / 10
    Print "Measuring transfered to Angle: " ; Angle
    Incr Bcount
    Led1_red = Switch_off
    Waitms 500
  Loop

End 'End execution '-------------------------------------------------------------------------------

Function Mb_cmps_measuring(ByVal I2c_address as Byte) As Word Local Lo_byte As Byte Local Hi_byte As Byte Local Cmps_slave As Byte Local Cmps_slave_read As Byte

  Cmps_slave = I2c_address
  Cmps_slave_read = Cmps_slave + 1
  Lo_byte = 0
  Hi_byte = 0
  I2cstart
  I2cwbyte Cmps_slave
  I2cwbyte 2
  I2cstop
  I2cstart
  I2cwbyte Cmps_slave_read
  I2crbyte Hi_byte , Ack
  I2crbyte Lo_byte , Nack
  I2cstop
  Mb_cmps_measuring = Makeint(lo_byte , Hi_byte)

End Function


Function Mb_cmps_firmware(ByVal I2c_address as Byte) As Byte Local Firmware As Byte Local Cmps_slave As Byte Local Cmps_slave_read As Byte

  Cmps_slave = I2c_address
  Cmps_slave_read = Cmps_slave + 1
  Firmware = 0
  I2cstart
  I2cwbyte Cmps_slave
  I2cwbyte 0
  I2cstop
  I2cstart
  I2cwbyte Cmps_slave_read
  I2crbyte Firmware , Nack
  I2cstop
  Mb_cmps_firmware = Firmware

End Function

Sub Mb_cmps_reset(byval I2c_address As Byte) Local Firmware As Byte Local Cmps_slave As Byte Local Cmps_slave_read As Byte

  Cmps_slave = I2c_address
  Cmps_slave_read = Cmps_slave + 1
  Firmware = 0
  I2cstart
  I2cwbyte Cmps_slave
  I2cwbyte 12
  I2cwbyte &H55
  I2cwbyte &H5A
  I2cwbyte &HA5
  I2cwbyte &HF2
  I2cstop


End Sub

Function Mb_cmps_newaddress(byval Current As Byte , Byval New As Byte) As Byte Local Firmware As Byte Local Cmps_slave As Byte Local Cmps_slave_read As Byte

  Cmps_slave = Current
  Cmps_slave_read = Cmps_slave + 1
  Firmware = 0
  I2cstart
  I2cwbyte Cmps_slave
  I2cwbyte 12
  I2cwbyte &HA0
  I2cwbyte &HAA
  I2cwbyte &HA5
  I2cwbyte New
  I2cstop

End Function </source>