AVR УРОК 39. Акселерометр LSM6DS3. Часть 4



 

    Урок 39

Часть 4

 

    Акселерометр LSM6DS3

 

Продолжаем работать с подключением акселерометра.

В прошлой части занятия мы закончили писать исходный код инициализации датчика.

Сегодня мы уже будем заниматься считыванием показаний нашего датчика по трем осям, которые время от времени нам нужно будет отправлять в шину USART. Для этого создадим функцию

 

void Accel_ReadAcc(void)

{

  _delay_ms(200);

}

//———————————————

void Accel_Ini(void)

 

Данная функция и будет заниматься обработкой показаний датчика и отправкой их для мониторинга в шину USART. Пока в ней только задержка. Напишем на неё протоип в заголовочный файл

 

void Accel_Ini(void);

void Accel_ReadAcc(void);

 

Затем вызовем её в бесконечном цикле в main()

 

while (1)

{

  Accel_ReadAcc();

}

 

В файле lsm6ds3.c напишем ещё одну функцию

 

void Accel_GetXYZ(int16_t* pData)

{

}

//———————————————

void Accel_ReadAcc(void)

 

Данная функция будет заниматься непосредственно выборкой данных из регистров и преобразованием их из пар в единые 16-битные целые числа. Причем данные значения могут быть и отрицательными. Кстати, здесь мы использовали тип значений необычный int16_t. Это то же самое что short. Кто программировал в Keil, тот данный тип знает. Мы постоянно там используем подобного рода типы.

Считывание данных осей постоянно с частотой, которую мы настроили в инициализации, происходит в шесть регистров (для каждой оси — по два)

 

image17

image18

image19

 

 

Так как регистры идут один за другим по адресам, то мы смело можем использовать чтение их всех в одном вызове, так как функция чтения из шины I2C, написанная нами ранее, это вполне предусматривает. Считаем эти данные в предварительно объявленный буфер, а затем с помощью давно известных битовых сдвигов переложим в другой буфер уже в три нормальные 16-битные значения

 

void Accel_GetXYZ(int16_t* pData)

{

  uint8_t buffer[6];

  uint8_t i=0;

  I2Cx_ReadData(0xD4,LSM6DS3_ACC_GYRO_OUTX_L_XL,6,buffer);

  for(i=0;i<3;i++)

  {

    pData[i] = ((int16_t)((uint16_t)buffer[2*i+1]<<8)+buffer[2*i]);

  }

}

 

Теперь продолжим писать функцию Accel_ReadAcc. Здесь мы также подготовим переменные, вызовем только что написанную функцию и разложим всё уже в свои локальные переменные

 

void Accel_ReadAcc(void)

{

  int16_t buffer[3] = {0};

  int16_t xval, yval, zval;

  Accel_GetXYZ(buffer);

  xval=buffer[0];

  yval=buffer[1];

  zval=buffer[2];

  _delay_ms(200);

 

Теперь зайдём в файл usart.c и напишем там функцию для отправки данных в шину USART сразу по несколько байтов в самом низу файла, иначе у нас будет очень и очень много кода, если мы будем отправлять данные по одному байту

 

//—————————————-

void USART_TX (uint8_t *str1, uint8_t cnt)

{

  uint8_t i;

  for(i=0;i<cnt;i++)

  USART_Transmit(str1[i]);

}

//—————————————-

 

Ну, и, конечно, напишем прототип в файле usart.h

 

void USART_Transmit( unsigned char data );

void USART_TX (uint8_t *str1, uint8_t cnt);

 

Вернёмся в нашу недописанную функцию. Сначала добавим глобальную переменную

 

unsigned char read_buf[10]={0};

char str1[30]={0};

 

Напишем в функции Accel_ReadAcc отправку данных в текстовом виде в шину USART

 

zval=buffer[2];

sprintf(str1,«X:%06d Y:%06d Z:%06drn», xval, yval, zval);

USART_TX((uint8_t*)str1,strlen(str1));

_delay_ms(200);

 

 

Соберём код, прошьём контроллер и запустим терминальную программу. Правда программа будет несколько другая, так как предыдущая порой не справляется с внушительным потоком. Я решил использовать HyperTerminal. Была найдена версия для современных операционных систем (ссылку дам в конце урока). Настроим в данной программе порт

 

image20  image21

 

Нажмём в программе кнопку «call» и Программа нам приблизительно 5 раз в секунду начнёт показывать значения наших осей, правда это не в единицах ускорений свободного падения, но всё это спокойно можно посчитать, учитывая, что у нас максимум 2G, значит 2G будет у нас 32768, а -2G — -32768. Соответственно 1G будет в 2 раза меньше и т.д. Понаклоняем макетницу с платой ненмного в разные стороны, и увидим, что показания постоянно меняются. Показания по оси Z приблизительно 1G означают, что данная ось у нас направлена вертикально и на неё постоянно действует ускорение земного притяжения 1G — она же гравитационная постоянная.

 

image23

 

Если вы смотрите мои уроки также и по STM, то вы уже знаете, что я также люблю писать программки под ПК и поэтому мы сейчас немного переделаем код вывода в шину USART, и уже посмотрим данные с осей в виде живого графика (ссылку на программу я также дам ниже). Правда программа работает только на 64-битных ОС. Сначала добавим ещё один глобальный буфер

 

char str1[30]={0};

uint8_t buf2[14]={0};

 

Код вывода строки в шину USART пока закомментируем, и напишем код вывода бинарных данных осей. Байты 0x11 и 0x55 вначале отправляем для того, чтобы программа на ПК привязывалась по ним к началу каждой посылки и не путала оси, также убавим немного задержку

 

//sprintf(str1,»X:%06d Y:%06d Z:%06drn», xval, yval, zval);

//USART_TX((uint8_t*)str1,strlen(str1));

buf2[0]=0x11;

buf2[1]=0x55;

buf2[2]=(uint8_t)(xval>>8);

buf2[3]=(uint8_t)xval;

buf2[4]=(uint8_t)(yval>>8);

buf2[5]=(uint8_t)yval;

buf2[6]=(uint8_t)(zval>>8);

buf2[7]=(uint8_t)zval;

USART_TX(buf2,8);

_delay_ms(30);

 

Соберём заново код и прошьём контроллер.

Запустим прогамму, настроим также её на наш порт и нажмем Start. Также покрутим немного плату и увидим изменения в графике показаний осей

 

image24

 

Мы видим, что показания изредка падают на 0, но это возможно из-за плохих контактов, либо программа просто не успевает обрабатывать, что скорей всего. В текстовом виде у нас никаких сбросов не происходило.

 

 

Предыдущая часть Программирование МК AVR Следующий урок

 

Исходный код

 

 

Техническая документация:

Документация на датчик

Документация на оценочную плату

 

Программа Hyper Terminal

Программа визуализации показаний

 

 

Приобрести плату Atmega 328p Pro Mini можно здесь.

Приобрести программатор USBASP USBISP с адаптером можно здесь USBASP USBISP 3.3 с адаптером

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

AVR Акселерометр LSM6DS3

8 комментариев на “AVR УРОК 39. Акселерометр LSM6DS3. Часть 4
  1. Алексей:

    День добрый! 

    Очень хочется увидеть урок с oled дисплеем 0.96" (шина I2c или TWI). Не планируете такой?

    • К сожалению, у меня такого нет.

      • Алексей:

        Понял, ну если будет у Вас возможность и желание попробовать его — буду рад освещению процесса тут. Дисплей интересный — пробовал играться с ним через arduino ide с готовой библиотекой. А вот нормально запустить его просто через atmel studio не вышло. Максимум инициализировать и точки ставить получалось.

        • Ну да, буду иметь в виду. То что работает с готовыми библиотеками ардуино, всегда нелегко запустить в Atmel Studio. Вот как раз сейчас я этим и занимаюсь. Пишу сценарий для работы с LAN-микросхемой enc28j60 под Atmel Studio, для которой под ардуино есть куча библиотек, приходится в них копаться и выкапывать оттуда некоторый передовой опыт.

  2. Алексей:

    LAN модуль — это тоже интересно! Спасибо за уроки … очень полезно))

  3. qwas:

    не устанавливается ns accel monitor, где можно скачать рабочую программу?

  4. товарищ,
    Большое спасибо за вашу публикацию, мне очень помогло использование atmega328pb с LSM6DS3
    Я использовал компилятор codevisionavr, и все работало нормально.
    если бы все знания были распространены, немой был бы намного лучше, и у нас было бы меньше бедности и социального неравенства
    Извините за ошибку перевода Google, здесь в Бразилии мы говорим на португальском
    объятий,
    Роналду Мартинс

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*