LinkedIn YouTube Facebook
Szukaj

Wstecz
IoT

[PRZYKŁAD] STM32 NUCLEO-L476RG i KA-Nucleo-UniExp

Po wygenerowaniu projektu należy uzupełnić kod o niezbędną funkcjonalność.

Na początek należy dołączyć bibliotekę string.h oraz zdefiniować adresy akcelerometru LIS35DE jako stałe.

/* USER CODE BEGIN Includes */
#include <string.h>
#define LIS35DE_WRITE_ADDRESS 0x38
#define LIS35DE_READ_ADDRESS 0x39

/* USER CODE END Includes */

Następnie zadeklarowano wszystkie niezbędne zmienne. To, jakie role będą pełnić opisałem w komentarzach do kodu.

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
uint16_t Temp_raw; // "surowe" wartosci odczytane z sensorow
int8_t x_raw, y_raw, z_raw; 
float temperatura, x_val, y_val, z_val; // przeliczone odczyty czujnikow
float z_offset = 0.14; // przesuniecie akcelerometru na osi Z
uint8_t Settings = 0x47; // wartosc jaka nalezy wpisac do rejestru CTRL_REG1 akcelerometru
char send[50]; // Tablica przechowujaca wysylana wiadomosc
char receive[50]; // Tablica przechowujaca wysylana wiadomosc
char bufor [10], odczytX[10], odczytY[10], odczytZ[10]; //odczyty w formie tablicy znakow
uint16_t size = 0;
/* USER CODE END PV */

Następnie znajdują się deklaracje funkcji używanych dalej w programie. Poniżej znajdują się także ich definicje oraz omówienie.

/* USER CODE BEGIN 0 */
void HC05_Send(char* command); //wysyla komendy do modulu Bluetooth
void konwertujNaString (char * tekst, float wartosc); //konwertuje wartosc float na lancuch znakow
/* USER CODE END 0 */

Funkcja HC05_Send ma za zadanie wysyłać komendę do modułu HC05 za pośrednictwem portu szeregowego. Funkcja dodaje także znaki „\r\n” niezbędne do potwierdzenia końca komendy.

void HC05_Send(char* command) {
	sprintf(send, "%s", command);
	strcat(send, "\r\n");
	size = strlen (send);
	HAL_UART_Transmit (&huart1, send, size, 100);
}

Funkcja konwertujNaString ma za zadanie konwersję zmiennej typu float na łańcuch znaków. Proces ten jest niezbędny, aby przesłać wartość przez interfejs szeregowy lub np. na ekran LCD. Funkcja jest identyczna jak w innym przykładzie: [PRZYKŁAD] KAmodMMA7361LC – akcelerometr analogowy i KA-NUCLEO-F411CE.

void konwertujNaString (char * tekst, float wartosc) {
	int t;
	char temp[2];
	itoa (abs((int)wartosc), temp, 10);
	if (wartosc < 0) // znak liczby
		strcpy (tekst, "-");
	else
		strcpy(tekst,"+");
	strcat(tekst, temp); // czesc calkowita
	strcat(tekst, "."); // kropka
	t = abs((int)((wartosc - (int)wartosc)*100));
	itoa (t, temp, 10);
	if (t< 10)
		strcat(tekst, "0"); // "0" po kropce gdy czesc ulamkowa jest mniejsza niz 0.1
							// Funkcja "itoa" go nie wstawia
	strcat(tekst, temp); //czesc ulamkowa
}

W funkcji main, po inicjalizacji peryferiów, program uruchamia przetwornik ADC. Następnie uruchamia akcelerometr wpisując do rejestru CTRL_REG1 (20h) odpowiednią wartość (47h). Po tym do modułu HC-05 wysyłane są komendy AT, które mają za zadanie skonfigurować urządzenie. Przed wysłaniem komendy AT+RESET, pin KEY ustawiany jest w stan niski. W ten sposób, moduł Bluetooth po resecie ustawi się w tryb oczekiwania na połączenie.

  /* USER CODE BEGIN 2 */
  
  HAL_Delay(3000);
  HAL_ADC_Start(&hadc1);
  HAL_I2C_Mem_Write (&hi2c1, LIS35DE_WRITE_ADDRESS, 0x20, 1, &Settings, 1, 100); //
  HC05_Send("AT"); //komenda testowa
  HC05_Send("AT+INIT"); //inicjalizacja modulu
  HC05_Send("AT+ORGL"); //reset ustawien
  HC05_Send("AT+NAME=KA-NUCLEO-UniExp"); //zmiana nazwy urzadzenia
  HC05_Send("AT+PSWD=0000"); //zmiana hasla urzadzenia
  HAL_GPIO_WritePin(BT_KEY_GPIO_Port, BT_KEY_Pin, 0);
  HC05_Send("AT+RESET"); //reset urzadzenia

  /* USER CODE END 2 */

W pętli głównej program pobiera z czujników wartości temperatury oraz przyspieszenia w każdej osi. Następnie oblicza i skaluje je w odpowiednich jednostkach. (temperaturę w stopniach Celsujsza, przyspieszenie w wielokrotnościach przyspieszenia ziemskiego). Za pomocą funkcji konwertujNaString wartości wpisywane są do określonych łańcuchów znaków. Na koniec dane wysyłane są przez port szeregowy do modułu Bluetooth.

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
	    if (HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK) { //odczyt z czujnika temperatury
			  Temp_raw = HAL_ADC_GetValue(&hadc1);
		  	  HAL_ADC_Start(&hadc1);
		  }
	  	temperatura = (1.8663-(3.3/4095.0)*Temp_raw)/0.01169; //konwersja temperatury
	  	HAL_I2C_Mem_Read (&hi2c1, LIS35DE_READ_ADDRESS, 0x29, 1, &x_raw, 1, 100);
	  	HAL_I2C_Mem_Read (&hi2c1, LIS35DE_READ_ADDRESS, 0x2b, 1, &y_raw, 1, 100);
	  	HAL_I2C_Mem_Read (&hi2c1, LIS35DE_READ_ADDRESS, 0x2d, 1, &z_raw, 1, 100);
	  	x_val = x_raw*(2.3/127);
	  	y_val = y_raw*(2.3/127);
	  	z_val = z_raw*(2.3/127) + z_offset;
	  	konwertujNaString(&odczytTemp, temperatura);
	  	konwertujNaString(&odczytX, x_val);
	  	konwertujNaString(&odczytY, y_val);
	  	konwertujNaString(&odczytZ, z_val);
	  	size = sprintf(send, "temperatura: %s\r\n", odczytTemp);
	  	HAL_UART_Transmit(&huart1, send, size, 100);
	  	size = sprintf (send, "ACC X:%s g, Y:%s g, Z:%s g\r\n", odczytX, odczytY, odczytZ);
	  	HAL_UART_Transmit(&huart1, send, size, 100);
	  	HAL_Delay(1000);
  }

  /* USER CODE END 3 */

Komunikacja Bluetooth wykorzystana została tu podobnie jak monitor portu szeregowego w Arduino. Wartości, wraz z odpowiednimi opisami, wysyłane są w formie tekstowej. Można je odczytać posiadając zainstalowaną na urządzeniu konsolę Bluetooth. Ja użyłem programu Bluetooth Terminal HC-05 na platformę Android. Umożliwia ona komunikację w formie tekstowej z każdym sparowanym urządzeniem.

Działanie przykładu przedstawiono na poniższym materiale wideo: