www.open-tager.ru
http://www.open-tager.ru/forum/

Умный датчик. Smart sensor.
http://www.open-tager.ru/forum/viewtopic.php?f=5&t=4949
Страница 10 из 17

Автор:  Pingvin [ 10 янв 2017, 16:17 ]
Заголовок сообщения:  Re: Умный датчик. Smart sensor.

Генератор случайных чисел на шумах внутреннего термодатчика.
Код:
uint32_t getTrueRandomNumber(void) {

  ADC_InitTypeDef ADC_InitStructure;

  //enable ADC1 clock
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

  // Initialize ADC 14MHz RC
  RCC_ADCCLKConfig(RCC_ADCCLK_HSI14);
  RCC_HSI14Cmd(ENABLE);
  while (!RCC_GetFlagStatus(RCC_FLAG_HSI14RDY))
    ;

  ADC_DeInit(ADC1);
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Backward;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_TRGO; //default
  ADC_Init(ADC1, &ADC_InitStructure);

  //enable internal channel
  ADC_TempSensorCmd(ENABLE);

  // Enable ADCperipheral
  ADC_Cmd(ADC1, ENABLE);
  while (ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN) == RESET)
    ;

  ADC1->CHSELR = 0; //no channel selected
  //Convert the ADC1 temperature sensor, user shortest sample time to generate most noise
  ADC_ChannelConfig(ADC1, ADC_Channel_TempSensor, ADC_SampleTime_1_5Cycles);

  // Enable CRC clock
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);

  uint8_t i;
  for (i = 0; i < 8; i++) {
    //Start ADC1 Software Conversion
    ADC_StartOfConversion(ADC1);
    //wait for conversion complete
    while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)) {
    }

    CRC_CalcCRC(ADC_GetConversionValue(ADC1));
    //clear EOC flag
    ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
  }

  //disable ADC1 to save power
  ADC_Cmd(ADC1, DISABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, DISABLE);

  return CRC_CalcCRC(0xBADA55E5);
}



Пример - случайные числа от 1 до 7
Код:
#define RANDOM_MIN (1)
#define RANDOM_MAX (7)

volatile uint32_t random_num;

random_num = RANDOM_MIN + getTrueRandomNumber()%RANDOM_MAX;

Автор:  LTagKirov [ 10 янв 2017, 18:27 ]
Заголовок сообщения:  Re: Умный датчик. Smart sensor.

Pingvin писал(а):
Генератор случайных чисел на шумах внутреннего термодатчика. Пример - случайные числа от 1 до 7
А теперь нагреть феном плату и посмотреть не получится ли всегда минимальное или максимальное число 8-)

Автор:  Alexies [ 10 янв 2017, 21:22 ]
Заголовок сообщения:  Re: Умный датчик. Smart sensor.

А вот так гораздо проще:
Код:
static unsigned long int next = 1;

int rand(void) // RAND_MAX assumed to be 32767
{
    next = next * 1103515245 + 12345;
    return (unsigned int)(next/65536) % 32768;
}

void srand(unsigned int seed)
{
    next = seed;
}

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

Автор:  Pacifist [ 11 янв 2017, 16:06 ]
Заголовок сообщения:  Re: Умный датчик. Smart sensor.

Рандом же нужен только при включении, разве нет?
Не проще отслеживать сколько времени удерживается кнопка?

Автор:  Alexies [ 11 янв 2017, 21:56 ]
Заголовок сообщения:  Re: Умный датчик. Smart sensor.

Pacifist писал(а):
Рандом же нужен только при включении, разве нет?
Не проще отслеживать сколько времени удерживается кнопка?

Понадобится несколько случайных чисел, значит - нужна функция-генератор. Проще всего использовать стандартный rand() из stdlib.h с адресом в качестве сида.
А датчики включаться будут автоматически при включении повязки, никаких кнопок нажимать не нужно

Автор:  Alexies [ 21 янв 2017, 19:30 ]
Заголовок сообщения:  Re: Умный датчик. Smart sensor.

Новости проекта
Потихоньку доделываю. Библиотека для работы с SSP (протоколом связи со смарт-сенсорами) стала юзабельной. Лежит отдельным репозиторием тут, чтобы было удобно подключать в разные проекты: https://github.com/DAlexis/lasertag-ssp

API для сенсора крайне простой, лежит в ssp-sensor.h ( https://github.com/DAlexis/lasertag-ssp ... sp-slave.h ):
Код:
/* Initialize SSP for slave device */
void ssp_sensor_init(void);

/* Send debug message over SSP.
 * Attention: this function should not be used when more than one device connected to master! */
void ssp_send_debug_msg(char *ptr, int len);

/* Should be called as frequently as possible from main loop or OS thread */
void ssp_sensor_task_tick(void);

/* Returns current state of leds and vibro according to animation tasks received from master */
void ssp_get_leds_vibro_state(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* vibro);

Тут, думаю, понятно по комментам. Чтобы это все работало, нужно реализовать функции-драйвера. В духе "передать буффер по шине", "проверить и получить ИК-сообщение" и т.п. Прототипы этих функций описаны в файле ssp-driver.h ( https://github.com/DAlexis/lasertag-ssp ... p-driver.h ) и в файле ssp-slave-driver.h ( https://github.com/DAlexis/lasertag-ssp ... e-driver.h ). В первом общие для повязки и для сенсора функции, во втором - сенсор-специфичные.

Интерфейс SSP со стороны повязки побольше, файл ss-master.h ( https://github.com/DAlexis/lasertag-ssp ... p-master.h ):
Код:
typedef struct {
   SSP_IR_Buffer buffer;
   SSP_Address sensor_address;
} SSP_IR_Message;

typedef struct {
   SSP_Address address[SSP_MAX_SENSORS_COUNT];
   uint16_t size;
} SSP_Registered_Addrs_List;

/* Initialize SSP for master device */
void ssp_master_init(void);

/* Should be called as frequently as possible from main loop or OS thread */
void ssp_master_task_tick(void);

/* Send IR buffer request to sensor with address specified. Result will be put into queue */
void ssp_push_ir_request(SSP_Address target_device);

/* Get IR buffer from queue and pop it. NULL if no data received */
SSP_IR_Message* ssp_get_next_ir_buffer();

/* Send animation task to sensor by address. Broadcast acceptable */
void ssp_push_animation_task(SSP_Address target, SSP_Sensor_Animation_Task* task);

/* Begin address discovering procedure */
void ssp_start_address_discovering();

/* Get addres discovering status. Non-zero if discovering in process */
uint8_t ssp_is_address_discovering_now();

/* Force stopping address discovering */
void ssp_stop_address_discovering();

/* Non-zero if ssp is busy now. This should be checked before any transmission over SSP */
uint8_t ssp_is_busy();

extern SSP_Registered_Addrs_List ssp_registered_addrs;

Тут тоже в комментариях указано назначение каждой из функций. Нужно реализовать драйвер для мастер-устройства из ssp-master-driver.h ( https://github.com/DAlexis/lasertag-ssp ... r-driver.h )

На данный момент есть все, кроме посылки ИК-сообщения с сенсора. Пока руки не дошли.

Автор:  Pingvin [ 24 янв 2017, 15:36 ]
Заголовок сообщения:  Re: Умный датчик. Smart sensor.

Тоже ковыряю платку.
Реализовал прием ИК и передачу.
Взялся за UART - вопросы есть по полудуплексу.

Нужен резистор подтягивающий к +3,3В?
Когда передача происходит, приемник тоже этот пакет ловит?


Смотрю в код - а где инициализация железа?
Как прием/передача реализованы, через прерывания?
Буфер кольцевой?

Автор:  Pingvin [ 25 янв 2017, 18:44 ]
Заголовок сообщения:  Re: Умный датчик. Smart sensor.

Запустил сегодня UART.
Порт настроил с подтяжкой к питанию, Open Drain


Да - он ловит свои же пакеты.
Отключать прием на время передачи?

Автор:  Alexies [ 26 янв 2017, 15:44 ]
Заголовок сообщения:  Re: Умный датчик. Smart sensor.

Pingvin писал(а):
Взялся за UART - вопросы есть по полудуплексу.
Нужен резистор подтягивающий к +3,3В?

Внешний резистор я не использую. Ставлю подтяжку на повязке при настройке GPIO, и отключаю подтяжку на сенсорах. Пока работает, но у меня только один сенсор подключен ещё. Вроде не должно быть проблем с любым количеством: главное, чтобы только один МК включал подтяжку.

Pingvin писал(а):
Когда передача происходит, приемник тоже этот пакет ловит?

Это зависит от того, как настроен последовательный порт. Но моя библиотека корректно работает в обоих вариантах, свои пакеты успешно отбрасывает.

Pingvin писал(а):
Смотрю в код - а где инициализация железа?
Как прием/передача реализованы, через прерывания?

В коде библиотеки нет работы с железом, она будет работать через драйвер. То есть пользователь должен, например, реализовать функцию передачи данных:
Код:
void ssp_send_data(uint8_t* data, uint16_t size);

и по получению байта вызывать функцию приема байта:
Код:
void ssp_receive_byte(uint8_t byte);

Так же и некоторые другие функции, см. коммертарии в файлах с заголовками драйвера.
По такому принципу устроены многие библиотеки для микроконтроллеров.

Прием и передача могут быть реализованы через прерывания, код рассчитан на это.
Pingvin писал(а):
Буфер кольцевой?

Смотря какой буфер. Буфер для эффектов - кольцевой, потому что это очередь: эффекты добавляются командами по шине, а извлекаются по мере "проигрывания". Буффер для входящих сообщений по шине линейный, в кольцевом там нет смысла, поскольку нет очереди: сообщения обрабатываются строго по одному (потому что протокол работает по принципу один запрос - один ответ)

Автор:  Pingvin [ 26 янв 2017, 19:12 ]
Заголовок сообщения:  Re: Умный датчик. Smart sensor.

Цитата:
Это зависит от того, как настроен последовательный порт. Но моя библиотека корректно работает в обоих вариантах, свои пакеты успешно отбрасывает.


А каким образом блокируется прием на время передачи?
Я сегодня экспериментировал.
Запрещал прерывания по приему, дожидался отправки всех символов (счетчиком) и завершения передачи последнего символа (проверкой флагов), затем разрешал прерывания по приёму.
Но если не делать задержку хотя бы небольшую - последний символ отлавливается, бывает.

Страница 10 из 17 Часовой пояс: UTC + 3 часа [ Летнее время ]
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/