Skocz do zawartości

Przeszukaj forum

Pokazywanie wyników dla tagów 'STM32'.

  • Szukaj wg tagów

    Wpisz tagi, oddzielając przecinkami.
  • Szukaj wg autora

Typ zawartości


Kategorie forum

  • Elektronika i programowanie
    • Elektronika
    • Arduino, ESP
    • Mikrokontrolery
    • Raspberry Pi
    • Inne komputery jednopłytkowe
    • Układy programowalne
    • Programowanie
    • Zasilanie
  • Artykuły, projekty, DIY
    • Artykuły redakcji (blog)
    • Artykuły użytkowników
    • Projekty - roboty
    • Projekty - DIY
    • Projekty - DIY (początkujący)
    • Projekty - w budowie (worklogi)
    • Wiadomości
  • Pozostałe
    • Oprogramowanie CAD
    • Druk 3D
    • Napędy
    • Mechanika
    • Zawody/Konkursy/Wydarzenia
    • Sprzedam/Kupię/Zamienię/Praca
    • Inne
  • Ogólne
    • Ogłoszenia organizacyjne
    • Dyskusje o FORBOT.pl
    • Na luzie
    • Kosz

Szukaj wyników w...

Znajdź wyniki, które zawierają...


Data utworzenia

  • Rozpocznij

    Koniec


Ostatnia aktualizacja

  • Rozpocznij

    Koniec


Filtruj po ilości...

Data dołączenia

  • Rozpocznij

    Koniec


Grupa


Znaleziono 35 wyników

  1. Witam, Chcialem sie was zapytac, czy ta funkcja jest poprawna? Czy takie rozwiazanie nie bedzie powodowac wyciekow pamieci? Czy rozmiar tablicy jest dobrze alokowany? char * subarray; char buffor[30]; uint8_t bufforElementsNumber = 0; char * getSubArray(int size, char array[]) { subarray = NULL; subarray = malloc(sizeof(char) * size); for (int i = 0; i < size; i++) { subarray[i] = array[i]; } return subarray; }
  2. Dodając krok po kroku trochę automatyki w mieszkaniu powstał projekt i realizacja sterownika rolet zewnętrznych. Główne cechy urządzenia: obsługa 7 rolet zdalny dostęp z dowolnego miejsca na świecie sterowanie przez Wifi sterowanie przez Bluetooth sterowanie przez sieć CAN automatyczny pomiar czasu pracy poszczególnych rolet harmonogram otwierania/zamykania rolet sterowanie grupowe tworzenie scen pobieranie aktualnego czasu z serwera NTP Sterownik został podzielony na dwie części, pierwsza to płytka z przekaźnikami i zasilaniem, druga płytka to układ sterowania wraz z modułami komunikacyjnymi. Główne elementy wykorzystane w sterowniku to: STM32F103C8T6 jako moduł Bluepill Moduł Wifi ESP-12 Bluetooth HC-05 Największym wyzwanie okazało się wykrywanie zakończenia pracy rolety. Było to niezbędne do automatycznego pomiaru czasu pracy, które jest wykorzystywane do określania pozycji pośrednich. Na początku testowałem wykrywanie prądu z wykorzystaniem modułu ACS711, ale niewielki prąd pobierany przez roletę podczas pracy powodował niestabilne pomiary z układu ACS711. Drugim pomysłem było wykorzystanie przekładników prądowych. Pomiary były stabilne, ale to rozwiązanie odpadło ze względu na fizyczne rozmiary takich przekładników, potrzebowałem użyć ich aż siedem sztuk. Ostatecznie zastosowałem rozwiązanie polegające na spadku napięcia na diodach, które aktywuje transoptor PC814. Rolety które posiadam mają wewnętrzne zabezpieczenie przed podaniem napięcia na oba uzwojenia silnika (góra, dół), jednak tak zaprojektowałem układ, aby sprzętowo nie było to możliwe. Pokazane jest to na poniższym rysunku. Program został napisany w C++ z wykorzystanie Arduino Core. ESP-12 pełni rolę konwertera komunikacyjnego, od strony wifi oferuje RestApi, konwertuje otrzymane wiadomości/zapytania na komunikację uart i wysyła do głównego procesora STM32. Na drugim porcie uart w STM32 jest podobna komunikacja z wykorzystaniem modułu bluetooth. Moduł BT aktualnie służy do przeglądania bieżących logów. Ponadto moduł posiada opcję komunikacji z wykorzystaniem sieci CAN, jestem bardziej fanem rozwiązań przewodowych tam gdzie jest to możliwe. Jak w mieszkaniu pojawi się więcej elementów automatyki to będę chciał całość przepiąć na sieć CAN zamiast Wifi. Sterowanie modułem odbywa się jak wspomniałem wyżej zapytaniami REST, na Banana Pro posiadam domowy serwer www, dołożyłem do niego prostą stronę w PHP, która pozwala w wygodny sposób wysyłać zapytania do sterownika. Do połączenia się ze sterownikiem poza domową siecią wykorzystuje OpenVPNa.
  3. Cześć, mam problem z komunikacją USART na stm32L452RE, poniżej zamieszczam kody, które napisałem przy pomocy znalezionych przykładów. Nie mam pojęcia czego tu jeszcze brakuje. Kod inicjalizacji USART: static void MX_USART2_UART_Init(void) { LL_USART_InitTypeDef USART_InitStruct; LL_GPIO_InitTypeDef GPIO_InitStruct; /* Peripheral clock enable */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2); /**USART2 GPIO Configuration PA2 ------> USART2_TX PA3 ------> USART2_RX */ GPIO_InitStruct.Pin = USART_TX_Pin|USART_RX_Pin; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; GPIO_InitStruct.Alternate = LL_GPIO_AF_7; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USART2 interrupt Init */ NVIC_SetPriority(USART2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0)); NVIC_EnableIRQ(USART2_IRQn); USART_InitStruct.BaudRate = 115200; USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; USART_InitStruct.StopBits = LL_USART_STOPBITS_1; USART_InitStruct.Parity = LL_USART_PARITY_NONE; USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; LL_USART_Init(USART2, &USART_InitStruct); LL_USART_ConfigAsyncMode(USART2); LL_USART_Enable(USART2); } Kod ciała przerwania USARTA: void USART2_IRQHandler(void) { /* USER CODE BEGIN USART2_IRQn 0 */ if(LL_USART_IsEnabledIT_TXE(USARTx_INSTANCE) && LL_USART_IsActiveFlag_TXE(USARTx_INSTANCE)) { /* TXE flag will be automatically cleared when writing new data in TDR register */ /* Call function in charge of handling empty DR => will lead to transmission of next character */ USART_TXEmpty_Callback(); } if(LL_USART_IsEnabledIT_TC(USARTx_INSTANCE) && LL_USART_IsActiveFlag_TC(USARTx_INSTANCE)) { /* Clear TC flag */ LL_USART_ClearFlag_TC(USARTx_INSTANCE); /* Call function in charge of handling end of transmission of sent character and prepare next charcater transmission */ USART_CharTransmitComplete_Callback(); } if(LL_USART_IsEnabledIT_ERROR(USARTx_INSTANCE) && LL_USART_IsActiveFlag_NE(USARTx_INSTANCE)) { /* Call Error function */ Error_Callback(); } /* USER CODE END USART2_IRQn 0 */ /* USER CODE BEGIN USART2_IRQn 1 */ /* USER CODE END USART2_IRQn 1 */ } Funkcje wykorzystane w powyższym przerwaniu: void USART_TXEmpty_Callback(void) { if(ubSend == (ubSizeToSend - 1)) { /* Disable TXE interrupt */ LL_USART_DisableIT_TXE(USARTx_INSTANCE); /* Enable TC interrupt */ LL_USART_EnableIT_TC(USARTx_INSTANCE); } /* Fill TDR with a new char */ LL_USART_TransmitData8(USARTx_INSTANCE, aStringToSend[ubSend++]); } void USART_CharTransmitComplete_Callback(void) { if(ubSend == sizeof(aStringToSend)) { ubSend = 0; /* Disable TC interrupt */ LL_USART_DisableIT_TC(USARTx_INSTANCE); /* Turn LED1 On at end of transfer : Tx sequence completed successfully */ //LED_On(); } } void Error_Callback(void) { __IO uint32_t isr_reg; /* Disable USARTx_IRQn */ NVIC_DisableIRQ(USARTx_IRQn); /* Error handling example : - Read USART ISR register to identify flag that leads to IT raising - Perform corresponding error handling treatment according to flag */ isr_reg = LL_USART_ReadReg(USARTx_INSTANCE, ISR); if (isr_reg & LL_USART_ISR_NE) { /* case Noise Error flag is raised : ... */ //LED_Blinking(LED_BLINK_FAST); } else { /* Unexpected IT source : Set LED to Blinking mode to indicate error occurs */ //LED_Blinking(LED_BLINK_ERROR); } } Na koniec użycie funkcji do wysłania danych w przerwaniu o low power LPTIM: void LPTIM1_IRQHandler(void) { /* USER CODE BEGIN LPTIM1_IRQn 0 */ /* Start USART transmission : Will initiate TXE interrupt after TDR register is empty */ LL_USART_TransmitData8(USARTx_INSTANCE, aStringToSend[ubSend++]); /* Enable TXE interrupt */ LL_USART_EnableIT_TXE(USARTx_INSTANCE); LL_LPTIM_ClearFLAG_ARRM(LPTIM1); LL_LPTIM_ClearFLAG_CMPM(LPTIM1); LL_LPTIM_ClearFlag_ARROK(LPTIM1); /* USER CODE END LPTIM1_IRQn 0 */ /* USER CODE BEGIN LPTIM1_IRQn 1 */ /* USER CODE END LPTIM1_IRQn 1 */ } Uprzejmie proszę o pomoc, bo nie mam pojęcia co tu jest nie tak. Za wszystkie odpowiedzi serdeczne dzięki.
  4. Posiadam płytkę STM32F407G-DISC1 oraz ekspander MCP23S08. Na podstawie kursu STM32F4 oraz STM32F1 próbuję zapalić diodę na wyjściu ekspandera. Korzystam z CUBEMX do konfiguracji mikrokontrolera oraz eclipse'a do programowania. Mam wrażenie, że wszystko robię w poprawny sposób, konfiguracja SPI jest zgodna z tą pokazaną w 9 części kursu STM32F1 a mimo to wyjścia ekspandera pozostają nieaktywne. Oczekuję, że zapali się dioda podpięta do pinu GP0. Poniżej dołączam mój kod: /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "stm32f4xx_hal.h" /* USER CODE BEGIN Includes */ #define MCP_IODIR 0x00 #define MCP_OLAT 0x0a /* USER CODE END Includes */ /* Private variables ---------------------------------------------------------*/ SPI_HandleTypeDef hspi1; /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_SPI1_Init(void); /* USER CODE BEGIN PFP */ /* Private function prototypes -----------------------------------------------*/ void mcp_write_reg(uint8_t addr, uint8_t value) { uint8_t tx_buff[]={0x40, addr, value}; HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(&hspi1, tx_buff, 3, HAL_MAX_DELAY); HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET); } /* USER CODE END PFP */ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration----------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_SPI1_Init(); /* USER CODE BEGIN 2 */ mcp_write_reg(MCP_IODIR, ~0x01); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ mcp_write_reg(MCP_OLAT, 0x01); while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** System Clock Configuration */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct; /**Configure the main internal regulator output voltage */ __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /**Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = 16; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = 8; RCC_OscInitStruct.PLL.PLLN = 64; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 4; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /**Initializes the CPU, AHB and APB busses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV8; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /**Configure the Systick interrupt time */ HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); /**Configure the Systick */ HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); /* SysTick_IRQn interrupt configuration */ HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); } /* SPI1 init function */ static void MX_SPI1_Init(void) { /* SPI1 parameter configuration*/ hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_2LINES; hspi1.Init.DataSize = SPI_DATASIZE_8BIT; hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; hspi1.Init.NSS = SPI_NSS_SOFT; hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi1.Init.TIMode = SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi1.Init.CRCPolynomial = 10; if (HAL_SPI_Init(&hspi1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } /** Configure pins as * Analog * Input * Output * EVENT_OUT * EXTI */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(RESET_GPIO_Port, RESET_Pin, GPIO_PIN_RESET); /*Configure GPIO pin : CS_Pin */ GPIO_InitStruct.Pin = CS_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(CS_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pin : DC_Pin */ GPIO_InitStruct.Pin = DC_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(DC_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pin : RESET_Pin */ GPIO_InitStruct.Pin = RESET_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(RESET_GPIO_Port, &GPIO_InitStruct); } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @param None * @retval None */ void _Error_Handler(char * file, int line) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ while(1) { } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t* file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  5. Witam wszystkich, jakiś czas temu przeniosłem się na procki STM32F1, sporo korzystałem z kursów Forbot więc postaram się także w jakiś sposób odwdzięczyć za czyjąś robotę. Dziś prezentuję moją implementację UARTa wspomaganą buforami FIFO i przerwaniami. Zaletą takiego rozwiązania jest, pod warunkiem nie wysyłania danych więcej niż szybkość transmisji, natychmiastowe wyjście z procedury wysłania bajtu, zaś przy odczycie danych, braku gubienia przychodzących bajtów jeżeli czytamy w zbyt długich odstępach czasu. Temat ten wielokrotnie pojawiał się tutaj w przykładach ale nigdzie nie znalazłem kompleksowego, zadowalającego mnie rozwiązania, prezentuję więc własne, może się komuś przydać albo udoskonalić. Moje rozwiązanie bazuje na HAL, jako implementacji FIFO użyłem kodu z wyguglanej kwerendy"Steve Karg Interrupt Safe Ring Buffer Library", chociaż w moim rozwiązaniu bezpieczeństwo na przerwania nie jest wymagane. Pomijając trywialne sprawy typu inicjalizacja FIFO, pinów, UARTA itd, zakładamy: UART_HandleTypeDef g_uart1; // poprawnie zainicjowany UART: 1) Odbieranie danych, założenia: FIFO_BUFFER g_rxFifo; // Bufor odbiorczy uint8_t g_rxBuffer; // Pomocniczy bajt do odbierania danych Inicjalizacjia, konieczne jest zainicjowanie odbierania na przerwaniach, najlepiej zrobić to zaraz przy inicjalizacji UARTa: HAL_UART_Receive_IT(&g_uart1, &g_rxBuffer, 1); Inicjalizuje to odbiór danych, 1 bajtu do buforu g_rxBuffer. Funkcja ta wraca od razu, rezultatem będzie zawołanie callbacka HAL_UART_RxCpltCallback który należy przekierować do poniższej funkcji: void serial1_RxCpltCallback() { FIFO_Put(&g_rxFifo, g_rxBuffer); HAL_UART_Receive_IT(&g_uart1, &g_rxBuffer, 1); } Funkcja ta wpisuje odebraną wartość do FIFO i natychmiast inicjuje odbieranie kolejnego bajtu. Funkcja do odbierania wygląda następująco, zwraca status: 0 - nie odebrano bajtu, 1 - odebrano bajt, przypisano pod podany wskaźnik. Niestety nie ma tutaj kontroli gdy odbieranie przepełni FIFO i zacznie gubić odbierane bajty, implementacja musi zapewniać w miarę sprawne odbieranie danych. Sprawę wyłączania i włączania przerwań opiszę później. uint8_t serial1_receive(uint8_t* byte) { __disable_irq(); if( FIFO_Empty(&g_rxFifo)) { __enable_irq(); return 0; } *byte = FIFO_Get(&g_rxFifo); __enable_irq(); return 1; } 2) Wysyłanie danych: FIFO_BUFFER g_txFifo; // Bufor nadawczy uint8_t g_txBuffer; // Pomocniczy volatile uint8_t g_txPending = 0; // Flaga informująca o trwającej transmisji bajtu. Zasada działania, początkowo txPending = 0 co oznacza że nic nie jest wysyłane, w takim przypadku przestawiamy ją na 1 i bajt danych wysyłamy bezpośrednio wołając HAL_UART_Transmit_IT, nie korzystając z fifo. Jednak zawołamy funkcję drugi raz zanim transmisja się zakończy i wywoła przewanie końca transmisji to txPending będzie miało wartość 1 co oznacza, że bajtu wysłać nie można i wpisujemy go do FIFO. Tutaj jeszcze sprawdzamy czy FIFO nie jest pełne, jeśli pełne go czekamy aż się zwolni i to jest jedyna możliwość gdy funkcja może trwać niespodziewania długo, ale dzięki temu jest gwarancja braku dropowania bajtów przy zbyt szybkiej transmisji. Jeśli komuś na tym nie zależy może usunąć pętlę while, pozostawiająć wykonanie FIFO_Put. void serial1_send(uint8_t byte) { __disable_irq(); if( g_txPending ) { while(!FIFO_Put(&g_txFifo, byte)) { __enable_irq(); __disable_irq(); } } else { g_txPending = 1; g_txBuffer = byte; HAL_UART_Transmit_IT(&g_uart1, &g_txBuffer, 1); } __enable_irq(); } Callback HAL_UART_TxCpltCallback należy przekierować do poniższej funkcji która działa w następujący sposób, jeśli fifo nie jest puste to pobiera z niego kolejny bajt i ponownie inicjuje transmisję na przewaniach, pozostając w stanie trwającej transmisji (txPending jest i pozostaje 1), natomiast jeśli fifo jest puste to oznacza to że nie ma już nic do transmisji i przestawiamy stan na txPending = 0. void serial1_TxCpltCallback() { if( !FIFO_Empty(&g_txFifo)) { g_txBuffer = FIFO_Get(&g_txFifo); HAL_UART_Transmit_IT(&g_uart1, &g_txBuffer, 1); } else { g_txPending = 0; } } 3) Słowo o włączaniu/wyłączaniu przerwań i innych niuansach, zauważmy że przy odbiorze danych kod HAL (funkcja HAL_UART_Receive_IT) jest wołana tylko z przerwania, natomiast przy wysyłaniu (funkcja) HAL_UART_Transmit_IT z przerwania bądź z programu głównego. Pisząc tą implementację tymczasowo odbieranie miałem w przedstawionej tutaj wersji zaś nadawanie jako klasyczne, blokujące HAL_UART_Transmit z programu głównego. I niestety pojawia się problem, gdy przerwanie HAL_UART_RxCpltCallback pojawi się w czasie trwającego, blokującego HAL_UART_Transmit gdyż HAL zaznacza ten obiekt jako locked i cokolwiek będziemy chcieli zrobić w czasie przerwania to nam się nie uda, dostaniemy status HAL_BUSY z HAL_UART_Receive_IT i transmisja stanie. Żaden z tutoriali poruszających transmisję UART na przerwaniach nie podaje tego niuansu a jest to akurat niezwykle istotne dla prawidłowego działania w dłuższym czasie. Rozwiązanie które przedstawiłem jest bezpieczne pod tym względem, każda funkcja kliencka wyłącza tymczasowo przerwania aby zabezpieczyć się przed tym problemem. 4) Ulepszenia. "Ręczne" fifo można przerobić na DMA, wysyłanie wielu bajtów można usprawnić pobierając z FIFO więcej niż jeden bajt, czego z pewnością prędzej czy później dokonam. Pozdrawiam, Remigiusz
  6. Czołem, mam pewien problem. Czytając reference manuala STM'a nie do końca rozumiem jak uruchomić przetwornik analogowo-cyfrowy pisząc na poziomie Low Layer ( założeniem projektu jest nie korzystać z bibliotek HAL'a). Jestem początkujący w programowaniu "bez HAL", dlatego proszę o wyrozumiałość i o pomoc/rady. Ustawienia ADC jakie wygenerowałem przy użyciu Cube'a wyglądają następująco: static void MX_ADC1_Init(void) { LL_ADC_InitTypeDef ADC_InitStruct; LL_ADC_REG_InitTypeDef ADC_REG_InitStruct; LL_ADC_CommonInitTypeDef ADC_CommonInitStruct; LL_GPIO_InitTypeDef GPIO_InitStruct; /* Peripheral clock enable */ LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC); /**ADC1 GPIO Configuration PC0 ------> ADC1_IN1 PC4 ------> ADC1_IN13 */ GPIO_InitStruct.Pin = LL_GPIO_PIN_0|LL_GPIO_PIN_4; GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; LL_GPIO_Init(GPIOC, &GPIO_InitStruct); /* ADC1 interrupt Init */ NVIC_SetPriority(ADC1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0)); NVIC_EnableIRQ(ADC1_IRQn); /**Common config */ ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B; ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT; ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE; LL_ADC_Init(ADC1, &ADC_InitStruct); ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE; ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_DISABLE; ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE; ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_SINGLE; ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_LIMITED; ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_PRESERVED; LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct); LL_ADC_SetOverSamplingScope(ADC1, LL_ADC_OVS_DISABLE); ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_ASYNC_DIV1; LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct); LL_ADC_EnableIT_EOC(ADC1); LL_ADC_DisableIT_EOS(ADC1); /**Configure Regular Channel */ LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_1); LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_1, LL_ADC_SAMPLINGTIME_2CYCLES_5); LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_1, LL_ADC_SINGLE_ENDED); } A ciało przerwania ADC tak: void ADC1_IRQHandler(void) { /* USER CODE BEGIN ADC1_IRQn 0 */ /* USER CODE END ADC1_IRQn 0 */ /* USER CODE BEGIN ADC1_IRQn 1 */ /* USER CODE END ADC1_IRQn 1 */ } Wstawiłem tylko wygenerowane fragmenty kodu, gdyż stwierdziłem że nie ma sensu wstawiać tu kodów wszystkich moich prób. Bardzo proszę o wskazanie mi, co mam gdzie wpisać, bądź jakich funkcji użyć, lub jeśli to nie problem napisać fragmenty uzupełniając powyższy kod, bo już sam nie wiem jak to mam zrobić. Za wszystkie odpowiedzi i pomoc bardzo dziękuję.
  7. Czołem koledzy, mam problem z Eclipse Version: Mars.2 Release (4.5.2) przygotowanego pod kurs STM32 F3 CUBE & HAL. Do programu wygenerowanego przez STM32CubeMX próbuję dołączyć własne pliki *.c i *.h source i header. Dodam, że robiłem takie rzeczy z powodzeniem dla Eclipse i AVR, nie przypominam sobie żadnych problemów. W tym wypadku ciągle dostaje błędy kompilacji m.in "no such file or directory" lub niewłaściwa liczba argumentów dla funkcji . Walczę z tym od kilku dni i mam wrażeniem, że nie będę potrafił prosto opisać moich problemów. Dlatego po prostu proszę was o wskazówkę. Jak właściwi załączyć do projektu CUBEMX w Eclipse pliki source i header *.c *.h zawierające moje własne funkcje. Dzięki za pomoc Zagadnienie rozwiązane, internety pomogły. http://www.openstm32.org/forumthread3284
  8. Witam, są to dopiero moje początki z STM32 Nucleo więc na wstępie proszę o wyrozumiałość. Posiadam model Nucleo 32 F042K6 oraz mostek L298n. Na mostku znajduje się 6 pinów ( ENA, In1, In2, In3, In4, ENB). Powiem na przykładzie arduino, gdy na ENA i ENB jest zworka prędkość jest albo 100% albo 0% w zależności od stanów. Gdy wyjmę zworki podłączałem te 2 piny do analogowych ( ENA, ENB), In'y do cyfrowych i wywoływałem funkcje w arduino: void forward(){ digitalWrite(in1, HIGH); digitalWrite(in2, LOW); analogWrite(ENA, 200); //wartosc od 100 do 255 digitalWrite(in3, HIGH); digitalWrite(in4, LOW); analogWrite(ENB, 200); } Było wszystko w porządku i właśnie o takie coś mi chodzi. Gdy znów wpiąłem zworki, podłączyłem 4 piny operujące stanami do Nucleo napisałem w STM Workbench, że silniki mają się kręcić do przodu oba też było dobrze: int main(void) { HAL_Init(); __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitTypeDef gpio; gpio.Pin = (GPIO_PIN_0 | GPIO_PIN_7 | GPIO_PIN_6 | GPIO_PIN_1); gpio.Mode = GPIO_MODE_OUTPUT_PP; gpio.Pull = GPIO_NOPULL; gpio.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOB, &gpio); while (1) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET); } } Problem jest taki że nie mogę poradzić sobie z ustawieniem prędkości obrotowej w nucleo na tych dwóch pinach. Dodam że TIM2 Kanał 1 jest na pinie PA0 natomiast TIM2 kanał 1 jest na pinie PA6. Korzystałem z wielu poradników jednak w internecie nic konkretnego ( co byłoby dla mnie zrozumiałe ) nie znalazłem. Proszę o jakieś konkretne rozwiązania. Chciałbym sterować w zakresie mniej więcej takim jak arduino, albo najlepiej od 0 do 100.
  9. Mam pytanie dot. definicji(stm32h7xx_hal_gpio.h): #define GPIO_SPEED_FREQ_LOW ((uint32_t)0x00000000U) /*!< Low speed */ #define GPIO_SPEED_FREQ_MEDIUM ((uint32_t)0x00000001U) /*!< Medium speed */ #define GPIO_SPEED_FREQ_HIGH ((uint32_t)0x00000002U) /*!< Fast speed */ #define GPIO_SPEED_FREQ_VERY_HIGH ((uint32_t)0x00000003U) /*!< High speed */ Jakie one oznaczają wartości częstotliwości pracy portu GPIO dla płytki Nucleo-H743ZI?
  10. Warto może dodać odcinek o sygnałach zegarowych i procedurze uruchamiania mikrokontrolera. Treker // Posty zostały wydzielone z poniższego tematu:
  11. Witam serdecznie. Jestem początkującym w STM. Właśnie przechodzę z AVR. Chcę wysłać przez UART liczbę a dokładnie przekonwertować ją na stringa poleceniem itoa. Rok temu już to zrobiłem, ale w między czasie padł mi dysk i wszystko straciłem. Zrobiłem funkcję: void send_integer(uint8_t n){ char *s; itoa ( n, s, 10 ); send_string(s); } ale podczas kompilacji wywala mi błąd ..\Src\main.c:308:12: warning: 's' is used uninitialized in this function [-Wuninitialized] itoa ( n, *s, 10 );
  12. Witam. Jestem początkujący więc z góry proszę o łagodne potraktowanie. Mam gotowy układ sterownika do z STM32 pracującym w sterowniku do drona Walkera Runner 250 Advance F3 SP Racing. Po zmianie konfiguracji w Betaflight Configurator układ zawiesił się i stracił komunikację z kompem. Proszę o informację w jaki sposób zresetować układ żeby wgrać firmware jeszcze raz. Próbowałem zewrzeć styk nRST do masy i na zwartym podłączyć ale nie przyniosło skutków. Czy macie jakieś pomysły? Proszę też o informację czy do aktualnego sterownika CP210x... jest konieczne wykonanie jeszcze jakiś operacji żeby chip STM32 stał się widoczny dla programu programującego. Próbowałem DfuSeDemo oraz UsbUpgradeTool. dzięki [ Dodano: 06-07-2018, 14:56 ] dodaje zdjęcie układu:
  13. Witam serdecznie, jestem kompletnie nowy w temacie elektroniki i dopiero zaczynam z tym przygodę. Od jakiegoś czasu myślę nad tematem jakiejś prostej elektroniki, którą mógłbym zrobić na podanej w temacie płytce(narzucona odgórnie), ale nic nie przychodzi mi do głowy stąd mój post tutaj. Czy mógłby ktoś zasugerować mi jakiś pomysł na niezbyt zaawansowaną, acz też nie za prostą elektronikę którą mógłbym zrealizować na tej płytce? Do tej pory do głowy przyszedł mi tylko termometr, alkomat, zamek magnetyczny i to w sumie tyle. Czekam na jakiś odzew i z góry dziękuję
  14. Witam! Jestem początkujący, jeśli chodzi o zabawę z płytkami Nucleo, a można powiedzieć, że zostałem już rzucony na głęboką wodę. W tym semestrze na uczelni mam projekt z Układów Cyfrowych i Mikroprocesorów na takiej właśnie płytce. Razem z większością osób grupy zakupiliśmy płytkę F103RB, widziałem, że na stronie są kursy i poradniki krok po kroku związane z tą płytką, więc na pewno będzie to przydatne, jednak szukam pomysłu na coś bardziej rozbudowanego, niż zapalająca się dioda po naciśnięciu przycisku. Termometr (w jakiejkolwiek postaci) raczej odpada, bo moi znajomi już się na to rzucili. Myślałem o barometrze, wilgotnościomierzu lub nawet zegarze cyfrowym, tylko nie znam stopnia trudności tych rzeczy, ani też nie wiem za bardzo jak się za coś takiego zabrać, bo tak jak mówiłem, jestem zupełnie zielony. Prosiłbym o jakąś podpowiedź w sprawie pomysłów na powyższe projekty, albo nawet propozycje jakiś nowych przeze mnie nieopisanych. Z góry dziękuję za pomoc, będę bardzo wdzięczny!
  15. Witam serdecznie. Czy jest możliwość w Atolic TrueStudio utworzenia nowego projektu z całą biblioteką HAL bez użycia kreatora CubeMX? Wybierając File -> New -> C project, mam możliwość utworzenia projektu tylko z biblioteką StdLib, a chciałbym mieć pełen pakiet driverów HAL.
  16. Chce wykorzystać kod z artykułu wraz z przerwaniem TIM_IT_Update, problem w tym, że gdy mam zsetupowany kontroler przerwań NVIC, to program nie może wyjść z TIM2_IRQHandler() pomimo tego, że czyszcze flage przez IM_ClearITPendingBit(TIM2, TIM_IT_Update); Sam TIM2 działa bez zarzutu, i jestem w stanie migać diodą w pętli głównej programu, ale tylko gdy pominę setup NVIC w kodzie. Co może być powodem tego problemu? Kompilator? Program pisze pod STM32f103C8 na eclipsowym OpenSTM. /** ****************************************************************************** * @file main.c * @author Ac6 * @version V1.0 * @date 01-December-2013 * @brief Default main function. ****************************************************************************** */ #include "stm32f10x.h" void TIM2_IRQHandler() { if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){ TIM_ClearITPendingBit(TIM2, TIM_IT_Update); if (GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13)) GPIO_ResetBits(GPIOC, GPIO_Pin_13); else GPIO_SetBits(GPIOC, GPIO_Pin_13); } } int main(void){ GPIO_InitTypeDef gpio; TIM_TimeBaseInitTypeDef tim; NVIC_InitTypeDef nvic; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); GPIO_StructInit(&gpio); gpio.GPIO_Pin = GPIO_Pin_13; gpio.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &gpio); TIM_TimeBaseStructInit(&tim); tim.TIM_CounterMode = TIM_CounterMode_Up; tim.TIM_Prescaler = 7200 - 1; tim.TIM_Period = 10000 - 1; TIM_TimeBaseInit(TIM2, &tim); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); TIM_Cmd(TIM2, ENABLE); // nvic.NVIC_IRQChannel = TIM2_IRQn; // nvic.NVIC_IRQChannelPreemptionPriority = 0; // nvic.NVIC_IRQChannelSubPriority = 0; // nvic.NVIC_IRQChannelCmd = ENABLE; // NVIC_Init(&nvic); while (1) { int timerValue = TIM_GetCounter(TIM2); if (timerValue > 1000) GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET); else GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_RESET); } }
  17. Witam. Mam problem, ponieważ napięcie na pinach ma tylko około 1V. Tak samo nie da się zaświecić diody wbudowanej LD2. Zmierzyłem napięcie i np. na pinach GPIOC napięcie ma około 1V. Dodam, że wcześniej było normalnie i mogłem z nich zasilić zwykłego LEDa. Czy coś się usmażyło?
  18. Cześć Chciałbym dowiedzieć się jak programować stm32 w LL. Jak do tego podejść?
  19. Od niedawna eksperymentuję z układami STM32 przy wykorzystaniu bibliotek HAL, narzędzia STM32CubeMX oraz środowiska AtollicSTUDIO. Nie znaczy to jednak, że nie mam doświadczenia z mikrokontrolerami - od kilku lat hobbystycznie programuję AVR-y i PIC32, zdarzało mi się także zajmować m.in. starszymi układami z rodziny 8051. Przejście na rodzinę STM32 wydawało mi się początkowo łatwe i bezbolesne, jednak teraz natknąłem się na dziwnego i mocno specyficznego buga, którego przyczyny nie jestem w stanie namierzyć. Przechodząc do meritum: Przeportowałem arduinową bibliotekę do obsługi modułów DCF77. Przepisałem ją w C, usunąłem nawiązania do bibliotek Arduino, zastępując je funkcjami standardowej biblioteki C, usunąłem też kilka błędów. Wygląda na to, że biblioteka działa - to znaczy przy dobrych warunkach propagacyjnych (szczególnie wieczorem) odbiera wiarygodnie wyglądające timestampy. Ponieważ bity parzystości używane przez DCF77 nie są dostatecznym zabezpieczeniem, biblioteka używa kilka sposobów sprawdzania poprawności odebranego czasu. Między innymi porównuje go z czasem systemowym. W oryginale była do tego używana jakaś biblioteka Arduino, ja użyłem time.h. Wiązało się to z koniecznością zdefiniowania własnej wersji funkcji time(), zwracającej czas systemowy z RTC w formie timestampa: time_t time (time_t * timer) { RTC_TimeTypeDef timeStruct; RTC_DateTypeDef dateStruct; struct tm dstTime; HAL_RTC_GetTime(&hrtc, &timeStruct, RTC_FORMAT_BIN); HAL_RTC_GetDate(&hrtc, &dateStruct, RTC_FORMAT_BIN); dstTime.tm_hour = timeStruct.Hours; dstTime.tm_min = timeStruct.Minutes; dstTime.tm_sec = timeStruct.Seconds; dstTime.tm_year = dateStruct.Year + 100; dstTime.tm_mon = dateStruct.Month - 1; dstTime.tm_mday = dateStruct.Date; return mktime(&dstTime); } W pętli głównej programu znajduje się następujący fragment, odpowiedzialny z synchronizację czasu i jego wyświetlanie na LCD: if ( (tmptime = DCF77_getUTCTime()) ) { printf("Time updated: %lu\r\n", tmptime); setRealTimeClock(tmptime); lastupdate = tmptime; } if (rtcTickFlag) { tmptime = time(NULL); tmupd = gmtime((const time_t*)&tmptime); snprintf(buffer, sizeof(buffer)-1, "%02d:%02d:%02d", tmupd->tm_hour, tmupd->tm_min, tmupd->tm_sec); PCD_GotoXYFont(1,1); PCD_Str(FONT_1X, (uint8_t*)buffer); snprintf(buffer, sizeof(buffer)-1, "%02d-%02d-%02d", tmupd->tm_mday, (tmupd->tm_mon)+1, (tmupd->tm_year)-100); PCD_GotoXYFont(1,2); PCD_Str(FONT_1X, (uint8_t*)buffer); if (lastupdate != 0) { tmupd = gmtime((const time_t*)&lastupdate); PCD_GotoXYFont(1,4); PCD_Str(FONT_1X, (uint8_t*)"Updated:"); snprintf(buffer, sizeof(buffer)-1, "%02d:%02d:%02d", tmupd->tm_hour, tmupd->tm_min, tmupd->tm_sec); PCD_GotoXYFont(1,5); PCD_Str(FONT_1X, (uint8_t*)buffer); snprintf(buffer, sizeof(buffer)-1, "%02d-%02d-%02d", tmupd->tm_mday, (tmupd->tm_mon)+1, (tmupd->tm_year)-100); PCD_GotoXYFont(1,6); PCD_Str(FONT_1X, (uint8_t*)buffer); } PCD_Upd(); rtcTickFlag = 0; } Funkcja setRealTimeClock() wygląda następująco: void setRealTimeClock (time_t tm) { RTC_TimeTypeDef timeStruct; RTC_DateTypeDef dateStruct; struct tm *dstTime; dstTime = gmtime(&tm); timeStruct.Hours = dstTime->tm_hour; timeStruct.Minutes = dstTime->tm_min; timeStruct.Seconds = dstTime->tm_sec; dateStruct.Year = (dstTime->tm_year)-100; dateStruct.Month = (dstTime->tm_mon)+1; dateStruct.Date = dstTime->tm_mday; HAL_RTC_SetTime(&hrtc, &timeStruct, RTC_FORMAT_BIN); HAL_RTC_SetDate(&hrtc, &dateStruct, RTC_FORMAT_BIN); } Na początku wszystko zdaje się działać prawidłowo. Układ startuje, RTC odlicza czas. Gdy pojawiają się odpowiednie warunki, moduł DCF77 zaczyna odbierać ramki i ustawia zegar. Na wyświetlaczu pojawia się właściwy czas UTC, jak również informacja o momencie ostatniej synchronizacji. Przez jakiś czas wszystko gra. Jednak w pewnym momencie dzieje się coś dziwnego. Aktualnie wyświetlany czas rozjeżdża się o jakieś osiem godzin do przodu. Na przykład wczoraj o 20.00 UTC pokazywał godziną 4.00 UTC dnia następnego. Żeby było jeszcze dziwniej informacja o ostatnio odebranej ramce wciąż pokazuje właściwy czas. Nie wiem na którym etapie pojawia się przekłamanie. Do konwersji czasu na formę tekstową używam przecież tych samych funkcji, Gdyby problem związany był z RTC albo moja funkcją time(), to przecież kolejne synchronizacje nie byłyby możliwe - biblioteka DCF77 wychwytywałaby sporą różnicę pomiędzy czasem systemowym i odebranym. W takim wypadku po odebraniu dwóch kolejnych prawidłowych ramek uznałaby, że czas systemowy jets zły i tak czy inaczej ustawiła RTC. Tymczasem na wyświetlaczu pojawiają się informacje o kolejnej udanej synchronizacji, a aktualny czas i tak jest wyświetlany błędnie... Ktoś ma pojęcie o co może chodzić? W załączniku przesyłam kompletny projekt, w razie gdyby przytoczone powyżej fragmenty kodu źródłowego okazały się niewystarczające. DCF77_LCD.zip
  20. Treker

    Fuzzy

    Przedstawiam mojego najnowszego robota klasy LineFollower Standard "Fuzzy". Z opisywaną konstrukcją pojawiam się na większości zawodów jakie organizowane są w ostatnim czasie. W porównaniu do moich poprzednich robotów Fuzzy nie został wyposażony w napęd tunelowy. Powodem tej decyzji była chęć testowania nowych algorytmów. Efekty mojej pracy łatwiej zauważyć na robocie bez docisku, ponieważ jest on trudniejszy to wysterowania przy większych prędkościach. Konstrukcja mechaniczna Robot standardowo wyposażony został w dwa silniki Pololu 10:1 HP z obustronnym wałem, na którym zamocowane zostały magnesy od enkoderów. Podwozie stanowi płytka PCB wykonana w Satlandzie. Czujniki wysunięte zostały do przodu na węglowej listewce. Koła wytoczone zostały na zamówienie. Całość, zależnie od dobranego akumulatora waży 70-100g. Elektronika Prezentowana konstrukcja to czwarty prototyp robota. Głównymi elementami części elektronicznej są: mikrokontroler STMF103RBT6, enkodery AS5040 oraz mostek TB6612. Konstrukcja może obsługiwać do 16 czujników KTIR. Po przeprowadzonych testach pozostałem jednak przy 8 transoptorach. Pozostałe połączenia z czujnikami pozwalają na wizualizację ich stanów poprzez diody LED. Schemat prototypu Prototyp W poprzedniej konstrukcji do komunikacji z otoczeniem wykorzystywałem złącza typu Goldpin o rastrze 0.5mm. Częste podpinanie i odpinanie dodatkowego osprzętu sprawiło, że złącza te szybko uległy uszkodzeniu wprowadzałem spore problemów. Dlatego w nowej wersji zastosowałem złącza firmy HARTING Flexicon, które rozwiązały mój problem. Szczerze mogę je polecić, nie miałem żadnych problemów od kiedy je stosuję. Ostateczna wersja elektroniki ze złączami HARTING Flexicon Oprogramowanie Program napisany został w języku C z wykorzystaniem biblioteki dostarczanej przed producenta STMów. Kod w głównej mierze składa się z dwóch części. Pierwsza odpowiedzialna jest za komunikację z otoczeniem, druga za podążanie za linią. Kontroler robota Robot może komunikować się z komputerem lub specjalnym kontrolerem za pomocą interfejsu USART. Możliwa jest również komunikacja przez moduły Bleutooth. Całość obsługiwana jest przez własny, prosty protokół do komunikacji. Algorytm pakuje wszystkie dane w ramki oraz oblicza sumę kontrolną. Rozwiązanie takie pozwoliło na bezbłędne przesyłanie wymaganych danych. Prototyp z modułem BlueTooth Podążanie za linią wykonane zostało w oparciu o 3 regulatory: PD - podążanie za linią, sprzężenie zwrotne od czujników 2x PID - sterowanie faktyczną prędkością silników, sprzężenie zwrotne od enkoderów magnetycznych Efekty Szczególną wagę przykładałem do precyzji przejazdu, która moim zdaniem jest zadowalająca - szczególnie na kątach prostych. Robot wygrał wszystkie zawody w kategorii LineFollower Standard w jakich brał udział. Zdarzyło mu się przegonić również niejednego robota z turbiną. W optymalnych, domowych warunkach średnia prędkość robota, to ponad 2m/s. Poniżej filmik z zawodów RoboMotion z prędkością około 1,4 m/s - nie był to najszybszy przejazd. Ostateczny wygląd robota W chwili obecnej konstrukcja różni się od powyższej jedynie kolorem opon i długością listewki od czujników. Później postaram dodać więcej zdjęć - szczególnie jeśli będzie z Waszej strony zainteresowanie czymś konkretnym. Podziękowania W tym momencie chciałbym podziękować firmom HARTING oraz TME, które wspierały pracy przy tym projekcie. Szczegóły z budowy robota można znaleźć na moim blogu: http://treker.eu/ Zachęcam do zadawania pytań, odpowiem praktycznie na każde
  21. Macio

    Rapid

    Rapid jest moją drugą konstrukcją micromouse. Zawiera ona kilka poprawek względem pierwszej (robot Wariat), z których najważniejszą jest użycie żyroskopu. Konstrukcja mechaniczna i zasilanie Robot zbudowany jest na płytce PCB, która stanowi jego podwozie. Założeniem projektu było uzyskanie nisko położonego środka cieżkości oraz jak najmniejszej masy. Dodatkowym atutem robota miała być jego mała szerokość, która pozwalałaby na poruszanie się po "skosie". Napędem robota są silniki Pololu 10:1 sterowane przez dwa mostki TB6612. Jako zasilanie wykorzystywane są akumulatory litowo-polimerowe o jak najmniejszym rozmiarze i niewielkiej masie. Z powodu małych pojemności konieczna jest częsta wymiana i ładowanie pakietów. W robocie używane są różne pakiety, różnych producentów. Mikrokontroler Sercem robota jest mikrokontroler STM32F405RGT6. O wyborze zdecydowała chęć nauki programowania mikrokontrolerów STM32 z najpotężniejszym rdzeniem Cortex-M4F oraz najmniejsza obudowa spośród wszystich procesorów rodziny STM32F4. Najważniejszymi cechami mikrokontrolera są: taktowanie 168MHz, 192kB RAM, 1MB flash, bardzo duża liczba timerów (m.in. ze sprzętową obsługą PWM oraz wyjść kwadraturowych enkoderów), wiele kanałów przetwornika ADC, DMA, sprzętowa obsługa liczb zmiennoprzecinkowych, wiele dostępnych interfejsów komunikacyjnych. Czujniki W robocie wykorzystano trzy rodzaje czujników: dalmierze optyczne, enkodery oraz żyroskop. Jako czujniki odległości wykorzystano diody SFH4511 oraz fototranzystory TEFT4300 (podłączenie takie samo jak w przypadku robota MIN7 autorstwa Ng Beng Kiat). Diody są sterowane impulsowo, każda z osobna. Wybranym żyroskopem jest analogowy czujnik ISZ-650 firmy Invensense. Jego zakres pomiarowy to +-2000st/s. O jego wyborze zdecydowała głównie dostępność i cena podczas zakupu. Podczas testów robota uszkodzono sensor, dlatego konieczna była wymiana. Zdecydowano się na moduł z żyroskopem L3GD20. Do podłączenia wykorzystano miejsce na wyświetlacz N3310 wraz z wyprowadzonym interfejsem SPI. Zamontowanie enkoderów obrotowych z magnesami na osiach silników powodowałoby poszerzenie całej konstrucji, więc zdecydowano się na użycie enkoderów liniowych wraz z odpowiednimi magnesami. Wykorzystane enkodery AS5304 oraz zamocowane magnesy na kołach robota przedstawiono na rysunkach poniżej. Użyte enkodery pozwalają uzyskać rozdzielczość 3520 impulsów na obrót koła, co daje w wyniku 0.028 mm/impuls. Interfejs użytkownika Założeniem projektu było wykorzystanie joysticka oraz wyświetlacza z telefonu Nokia 3310. Obecnie oprogramowanie nie zawiera obsługi wyświetlacza, dlatego nie jest on zamontowany. Do wyboru prostych komend służy joystick oraz zamontowany buzzer. Buzzer służy także jako powiadomienie o charakterystycznych sytuacjach w labiryncie, np. wykrycie ścianki, dojechanie do środka labiryntu. Oprogramowanie Program opiera się o cykliczne wywoływanie funkcji z częstotliwością 1kHz. W funkcji tej wykonywane są pomiary czujników, aktualizowana jest pozycja robota oraz wyliczane są wartości współczynnika wypełnienia PWM na silniki. Robot posiada trapezoidalny profil sterowania prędkością. Implementacja i zasada działania jest bardzo podobna jak w artykule [Programowanie] Sterowanie robotem mobilnym klasy (2,0). Przeszukiwanie robota odbywa się z użyciem algorytmu floodfill. Po znalezieniu środka labiryntu, robot rozpoczyna wyznaczanie najszybszej ścieżki. Do tego celu użyto zmodyfikowanego algorytmu floodfill, którego wagami jest czas przejazdu. Podsumowanie Robot Rapid zachowuje się w labiryncie dosyć stabilnie i przewidywalnie. Jest to bardzo ważna cecha, ponieważ pozwala na dalszą pracę nad konstrukcją oraz rozwijanie oprogramowania. Pomysłów na poprawienie działania robota jest wiele. Ograniczeniem jest jedynie poświęcony temu czas. Galeria Osiągnięcia I miejsce w kategorii Micromouse na zawodach Robotic Arena 2012 II miejsce w kategorii Micromouse na zawodach Robomaticon 2013 I miejsce w kategorii Micromouse na zawodach Trójmiejski Turniej Robotów 2013 I miejsce w kategorii Micromouse na zawodach ROBO~motion 2013
  22. Harnas

    Stuart

    Witam. Po pierwszej konstrukcji jaką był linefollower postanowiłem zrobić coś ambitniejszego. Wybór padł na robota typu micromouse. Praktycznie wszystkie części zostały zasponsorowane prze moją szkołę. Elektronika Robotem steruje mikrokontroler z rodziny stm32f103 taktowany kwarcem 8Mhz i z włączoną wewnętrzną pętlą PLL, która mnoży zegar x9, taktując ostatecznie procesor 72MHz. Jako mostki do silników zostały użyte 2x tb6612, po jednym na silnik. Jako czujniki początkowo używane były sharpy 5 i 10 cm a od niedawna są to analogowe dalmierze zbudowane z diody ir i fototranzystora. Do zasilania używam akumulatora modelarskiego typy li-pol 2 celowego o pojemności 500mAh. Silniki są zasilane bezpośrednio z akumulatora przez diodę zapobiegająca uszkodzeniu mostków na skutek błędnego podłączenia akumulatora. Elektronika również jest zasilana przez połączone kaskadowo stabilizatory 5V i 3.3V które też są zabezpieczone osobną diodą. Mechanika Podstawą jest płytka drukowana wykonana z laminatu 1.5mm wykonana w firmie Satland Prototype . Silniki to Pololu HP 30:1 z przedłużona osią. Jako enkodery początkowo służyły wydrukowane tarcze 5 czarnych pół i po dwa czujniki TCRT1000 dając 20 impulsów na obrót wału silnika. Obecnie są to enkodery wymontowane z myszki kulkowej. Oprogramowanie Cały program został napisany w języku C w środowisku Atollic TrueSTUDIO. Mysz posiada algorytm mapowania oraz rozwiązywania labiryntu, jednak wykonywanie korekcji wobec ścian nie jest tak skuteczne aby przejechanie dużego labiryntu obyło się bez dotknięcia ściany. Obsługa enkoderów jest wykonana sprzętowo przy użyciu jednego timera na każdy enkoder w specjalnym trybie przeznaczonym do obsługi enkoderów kwadraturowych. Filmy i zdjęcia wersji z sharpami i enkoderami wydrukowanymi na papierze - stan na Robotic Arena 2011 https://www.youtube.com/watch?v=kMqzrvSACqc Aktualny stan - dalmierze i enkodery z myszki - Robotic Tournament 2012 https://www.youtube.com/watch?v=Kcb8uWGm-as Podziękowania dla użytkownika Matmaniak za filmik z zawodów Istrobot 2012: https://www.youtube.com/watch?v=FSQFybaACO0https://www.youtube.com/watch?v=qSlVX2fVSts Płynne skręty, nowy labirynt i parę innych rzeczy. https://www.youtube.com/watch?v=rufoc3rPTvI Udział w zawodach: Robotic Arena 2011 - 4. miejsce. Robotic Tournament 2012 - 4. miejsce. Istrobot 2012 - 1. miejsce. Roboxy 2012 - 2. miejsce. Pozdrawiam
  23. Krzema

    Enova

    Cześć, przedstawiamy Wam naszego pierwszego robota zbudowanego w ramach drużyny Magnat Cyber Forge Team. W skład drużyny wchodzą: mechanik Mateusz Piotrzkowski, elektronik Szymon Zagórnik oraz programista Piotr Krzemiński. Konstrukcja powstawała przez prawie 2 lata - od pierwszej burzy mózgów i szkiców na komputerze, przez zbieranie funduszy, wykonanie elementów, montaż, programowanie, aż do pierwszego startu w konkursie. Robot ma już swoje lata, lecz mimo to postanowiliśmy go tu opisać. Koncepcja i napęd robota Panujący obecnie w robotach sumo trend skłania do wyboru konstrukcji z dwoma kołami napędowymi. Roboty o takiej strukturze napędu są tanie w budowie, a przy tym zapewniają dobre przyleganie krawędzi tnącej ostrza do podłoża. Problemem w ich przypadku jest nieoptymalne przeniesienie ciężaru robota na podłoże oraz duży moment bezwładności robota. Konstrukcja z czterema kołami napędowymi jest mało popularna lecz rozwiązuje wiele problemów robotów wyposażonych tylko w dwa koła. Pierwszą zaletą jest możliwość zapewnienia przeniesienia prawie całego ciężaru robota przez opony. Kolejną zaletą jest przesunięcie środka obrotu robota do przodu oraz łatwość wpadania w poślizg robotem. Zalety te są nieznaczące w obliczu problemów z zamocowanym nieruchomo ostrzem. W przypadku gdy koła stanowią trzy niezbędne punkty podparcia bardzo trudno jest zamocować ostrze z taką dokładnością aby przylegało do podłoża. Zdecydowaliśmy się zaryzykować. Wybór padł na konstrukcję z czterema kołami oraz ruchome mocowanie ostrza - tak aby połączyć zalety struktur napędu z dwoma i czterema kołami. Szukając silników napędu kół robota wybór ograniczyliśmy do 3 firm oferujących jakościowo najlepsze mikrosilniki elektryczne na świecie - firm Maxon, Faulhaber i Portescap. Głównym ograniczeniem determinującym wybór silników do robota minisumo jest ich maksymalna długość. Zdecydowaliśmy że każde z kół będzie napędzane niezależnie, więc długość silnika wraz z przekładnią i enkoderem nie mogła przekroczyć 50 mm. Po przejrzeniu ofert wymienionych firm okazało się że najmocniejszą konfiguracją o wymaganych wymiarach są silniki Faulhaber 1717 006 SR wraz z przekładnią 16/7 14:1 oraz enkoderami IE2. Silniki te są marginalnie mocniejsze od popularnie stosowanych mikrosilników firmy pololu, lecz mają wielokrotnie większą żywotność. Zdarzały nam się sytuacje całkowitego zatrzymania wszystkich 4 silników na regulaminowe 3 minuty walki a silniki dalej pracują jak nowe. Mechanika Konstrukcja robota składa się z 11 elementów. Siedem z nich zostało zoptymalizowanych pod kątem wykonania metodami skrawania z aluminium, stali oraz węglika wolframu. Pozostałe 4 elementy zostały wydrukowane w technologii PolyJet. Głównym elementem konstrukcyjnym jest płyta centralna. Przykręcone do niej są: tulejki mocujące silniki, element mocujący ostrze, mocowania czujników robota przeciwnika oraz płytka drukowana sterująca robotem. Poniżej znajduje się jeden z siedmiu rysunków wykonawczych tego elementu. Element mocujący ostrze wykonano ze stali 40 HM utwardzonej do wartości 50 HRC. Dzięki temu wypolerowana powierzchnia trudno się rysuje, a przeciwnicy gładko prześlizgują się na zamocowane wyżej rogi. Element ten posiada oś obrotu oraz jest dociskany dwoma sprężynami - niezależnie z każdej strony. Sprawia to że ostrze dociśnięte jest równomiernie do podłoża. Ostrza które stosujemy są wykonane dla nas na zamówienie z węglika wolframu. Poniżej zdjęcie porównawcze tego ostrza ze starą wersją zintegrowaną z mocowaniem do płyty centralnej. Felgi robota mają średnicę 24 mm. Posiadamy kilka kompletów z poliamidu i kilka z aluminium. Nie zauważyliśmy większej różnicy w działaniu robota na różnych kompletach. Opony mają zewnętrzną średnicę 30 mm co daje grubość opon równą 3mm. Przetestowaliśmy wiele materiałów na opony od firmy Smooth-On: Mold Star 15, Mold Star 30, Mold Max 20, Vyta Flex 10, Vyta Flex 30, Vyta Flex 20. Ten ostatni wykazał najlepsze własności mechaniczne i jest przez nas aktualnie stosowany. Do mieszanki dodajemy czarny barwnik, co zwiększa nieco nieco lepkość opon. Waga robota waha się w zależności od zastosowanych felg i baterii od 460 do 495 gramów. Elektronika Płyta sterowania robota to laminat FR4 o grubości 0.8mm. By spełnić wymagania związane z fizycznym rozmieszczeniem układów na płytce, wykorzystaliśmy technologię produkcyjną umożliwiającą nam użycie ścieżek o szerokości 0.2mm oraz rastrze podobnej szerokości. Znajdujące się na płytce układy zapewniają prawidłową pracę robota w trybie domyślnym tj. walka na ringu (bez opcji wybierania taktyki i różnych trybów). Program robota wykonywany jest przez wcześniej wspomniany 32-bitowy mikrokontroler ST32F107R8T6. Został on wybrany ze względu na aż cztery dostępne timery, które są niezbędne do obsługi sygnałów z enkoderów silników. Na płycie sterowania znajdują sie również cztery mostki H, złącza od czujników przeciwnika sześć transoptorów i dwa stabilizatory napięcia na 3.3V i 5V. Moduł interakcji użytkownika z robotem stanowi płytka drukowana umieszczona pod górną pokrywą robota. Jest ona w znacznym stopniu mniej skomplikowana od płytki sterującej, niemiej jednak zawiera ona oddzielny mikroprocesor STM32F103CVT. Obsługuje on wyświetlacz OLED o rozdzielczości 128x64 piksele poprzez interfejs SPI. Wykrywa on również sygnał z zmieszczonego na płytce odbiornika podczerwieni oraz czterech przycisków stykowych. Dzięki przyciskom lub bezprzewodowo z pomocą pilota RC5 użytkownik jest w stanie włączyć robota i wybrać algorytm pracy robota wyświetlany na wyświetlaczu OLED. Komunikacja między górnym i dolnym mikroprocesorem odbywa się za pomocą interfejsu UART. Obie płytki drukowane są połączone ze sobą taśmą FFC. Zasilanie Zastosowaliśmy dwukomorową baterię litowo-polimerową, która przy maksymalnym naładowaniu daje 8.4V. Nie wyróżnia się ona niczym szczególnym poza rozmiarem i kształtem, który jest idealnie dopasowany do konstrukcji robota i wewnętrznego rozmieszczenia elementów. Pojemność baterii to 900 mAh Czujniki Sensorami umożliwiającymi wykrywanie przeciwnika są popularne Sharpy GP2Y0D340K. Są to czujniki IR o zasięgu do 40 cm. Są cyfrowe, tj. wskazują pojawienie się obiektu lub jego brak. W środku sensora umieszczony jest układ cyfrowy kondycjonujący otrzymaną wiązkę podczerwieni oraz emitujący cyfrowy sygnał wykrycia do mikrokontrolera. Zasilany jest wyłącznie 5V więc sygnał Vout również jest na tym poziomie. Fakt ten nie komplikuje układu, gdyż użyty mikrokontroler ma wejścia kompatybilne z 5V mimo, że sam jest zasilany na 3.3V. W celu skutecznego wykrywania przeciwnika umieszczono aż 6 sensorów ułożonych w konfiguracji: 2 patrzące do przodu, 2 pod skosem 45 stopni oraz 2 patrzące na boki robota. Jednostki obliczeniowe Dolna płytka zawiera główny procesor STM32F107 taktowany zegarem o częstotliwości 72 MHz. Zajmuje się przetwarzaniem informacji z czujników linii oraz przeciwnika, a także wysterowuje silniki korzystając z wbudowanych fabrycznie enkoderów magnetycznych i regulatora PID. Na górnej płytce znajduje się drugi procesor STM32F103 (również 72 MHz) zajmujący się obsługą wejścia/wyjścia czyli przycisków, wyświetlacza i wbudowanego odbiornika podczerwieni. Taki podział zadań pomiędzy dwa procesory wydaje się zbędny/przesadzony, lecz jest to pozostałość z pierwszych wersji robota.. Programowanie Do komunikacji z robotem użyto dwóch interfejsów: SWD (Serial Wire Debug) – szeregowa odmiana popularnego interfejsu JTAG. Umożliwia on programowanie oraz debugowanie mikrokontrolera sterującego. Do komunikacji między dwoma modułami (mikroprocesorami) oraz komunikacji komputer – mikroprocesor użyto interfejsu UART. Fizyczne połączenie robota z komputerem stanowi złącze MicroHDMI. Zostało ono wybrane ze względu na liczbę dostępnych pinów oferowane przez standard HDMI, trwałość mechaniczną i dostępność. Medium łączące wymienione interfejsy i komputer jest przejściowa płytka drukowana z standardowymi złączami dla programatorów. Rysunek poniżej przedstawia omawianą „przejściówkę”. Oprogramowanie Program dla robota pisany jest w języku C, z użyciem Standard Peripheral Library. W newralgicznych miejscach, aby przyśpieszyć kod, wykonywane są operacje bezpośrednio na rejestrach - dzięki temu został zachowany balans między czytelnością a wydajnością kodu. Jeśli chodzi o IDE, początkowo wykorzystywane było TrueSTUDIO Lite, lecz ze względu na swój limit wielkości programu wynikowego (32 kB?) byliśmy zmuszeni do przejścia na CoIDE. Silniki wysterowywane są regulatorem PID, lecz tak naprawdę tylko człon P jest aktywny. Zaimplementowany został pełny regulator PID, lecz okazało się, że na członie P robot zachowuje się dobrze i nie ma potrzby uaktywniać pozostałych współczynników. Magnetyczne enkodery wbudowane w silnik dostarczają aż 7168 impulsów na obrót, co zapewnia wysoką dokładność. Został wykorzystany wbudowany w STM32F107 interfejs dla enkoderów, dzięki czemu zliczanie impulsów sygnału kwadraturowego odbywa się niejako "w osobnym wątku" - nie są potrzebne przerwania, wystarczy odczytywać położenie koła ze wskazanego rejestru. Dzięki czterem czujnikom linii z przodu, możemy obliczyć w przybliżeniu kąt pod jakim podjeżdżamy do linii. Wystarczy prosta trygonometria - znamy odległość między czujnikami, znamy też dystans jaki robot przejechał od momentu zobaczenia linii zewnętrznymi czujnikami do momentu zauważenia jej czujnikami wewnętrznymi. Znając kąt pomiędzy osią robota a linią, możemy odpowiednio wykonać manewr wycofania się ku środkowi planszy. Odbiornik podczerwieni na górnej płytce służy nam głównie do odbierania sygnałów z pilotów sędziowskich. Zastosowaliśmy własny odbiornik przede wszystkim aby zaoszczędzić na miejscu, lecz również aby móc odbierać niestandardowe komendy dla robota, np. wskazówki dotyczące taktyki. Dzięki "deweloperskiej" wersji aplikacji Sumo Remote możemy wysyłać w zasadzie dowolny kod do robota - po dopracowaniu funkcja ta będzie dostępna publicznie. Monochromatyczny wyświetlacz OLED o rozdzielczości 128x64 umieszczony na górnej płytce umożliwia wybór taktyk, a także wyświetlanie informacji testowych. Nie posiada on wbudowanej czcionki, więc konieczna była implementacja wyświetlania własnych czcionek/obrazków. Aby zaoszczędzić miejsce w pamięci Flash procesora, obrazy kompresowane są algorytmem RLE za pomocą konwertera w postaci aplikacji na PC, po czym na robocie dekompresowane są w locie. Dzięki temu możemy użyć dużych i czytelnych czcionek, czy też schematycznych ikon obrazujących manewry robota. Krótkie demo działania wyświetlacza: (muzyka niestety nie jest odtwarzana z robota ). Po więcej szczegółów zapraszamy na naszą stronę: http://mcft.eu/_portal/page/knowledge_base/cat/6/Enova_MiniSumo#art_Enova_MiniSumo. Osiągnięcia Sezon 2013/2014: [*]1. miejsce na Roboxy 2014 w kategorii Minisumo [*]1. miejsce na Trójmiejskim Turnieju Robotów 2014 w kategorii Minisumo Deathmatch [*]3. miejsce na Trójmiejskim Turnieju Robotów 2014 w kategorii Minisumo [*]1. miejsce na Cyberbot 2014 w kategorii Minisumo Deathmatch [*]2. miejsce na Cyberbot 2014 w kategorii Minisumo [*]1. miejsce na Robot-SM 2014 w Göteborgu w kategorii Minisumo [*]1. miejsce na Ogólnopolskich Zawodach Robotów ROBOmotion 2014 w kategorii Minisumo [*]1. miejsce na Ogólnopolskich Zawodach Robotów ROBOmotion 2014 w kategorii Minisumo Deathmatch [*]1. miejsce na Robotic Tournament 2014 w kategorii Minisumo [*]1. miejsce na Robotic Tournament 2014 w kategorii Minisumo Deathmatch [*]1. miejsce na Copernicus Robots' Tournament 2014 w kategorii Minisumo [*]1. miejsce na Copernicus Robots' Tournament 2014 w kategorii Minisumo Deathmatch [*]1. miejsce na Robotic Arena 2013 w kategorii Minisumo Debel (z robotem Mirror Mateusza Paczyńskiego) [*]2. miejsce na Robotic Arena 2013 w kategorii Minisumo Enhanced [*]2. miejsce na Robotic Arena 2013 w kategorii Minisumo Classic [*]2. miejsce na Sumo Challenge 2013 w kategorii Minisumo+ [*]1. miejsce na Sumo Challenge 2013 w kategorii Minisumo [*]1. miejsce w konkursie robotów Gdańskich Dni Elektryki Młodych 2013 w kategorii Minisumo Sezon 2012/2013: [*]1. miejsce na Leś-Tech 2013 w kategorii Minisumo [*]1. miejsce na Roboxy 2013 w kategorii Minisumo [*]1. miejsce na CybAiRBot 2013 w kategorii Minisumo [*]1. miejsce na Robocomp 2013 w kategorii Minisumo [*]1. miejsce na ROBOmotion 2013 w kategorii Minisumo Deathmatch [*]1. miejsce na ROBOmotion 2013 w kategorii Minisumo [*]1. miejsce na Copernicus Robots Tournament 2013 w kategorii Minisumo Deathmatch [*]1. miejsce na Copernicus Robots Tournament 2013 w kategorii Minisumo [*]3. miejsce na Trójmiejskim Turnieju Robotów 2013 w kategorii Sumo² [*]1. miejsce na Trójmiejskim Turnieju Robotów 2013 w kategorii Minisumo [*]1. miejsce na Robotic Tournament 2013 w kategorii Minisumo [*]1. miejsce na RobotChallenge 2013 w Wiedniu w kategorii Minisumo [*]1. miejsce na Robomaticon 2013 w kategorii Minisumo [*]1. miejsce na T-BOT 2013 w kategorii Minisumo [*]1. miejsce na Robotic Arena 2012 w kategorii Minisumo Enhanced [*]2. miejsce na Robotic Arena 2012 w kategorii Minisumo Poniższy film prezentuje walki Enovy na konkursie RobotChallenge 2013 w Wiedniu: A tutaj kompilacja walk Enovy z konkursu Robocomp 2013 w Krakowie:
  24. Luny

    2Weak4U

    Cześć! Jako że już po sezonie to postanowiłem opisać tu moją i mateuszm konstrukcję. Robot powstał w ramach rekrutacji do koła naukowego robotyków KoNaR i debiutował na Robotic Arenie 2015. Był to nasz debiut w konstruowaniu robotów, ponieważ wcześniej żaden z nas tego nie robił. Mechanika Głównym założeniem mechaniki robota było wykorzystanie w pełni maksymalnej dopuszczalnej masy oraz skupienie jej w podstawie. W osiągnięciu tego celu pomógł nam projekt Autodesk Inventor, w którym to został wykonany szczegółowy projekt robota uwzględniający wszystkie drobne elementy mechaniczne. Podstawa robota została wykonana z trzech elementów: - ostrze z węglika spiekanego - płytka stalowa 3mm - płytka górna, 2mm, która łączyła dwa elementy wymienione wyżej W płytkach zostały wycięte otwory, w których następnie umieszczone były małe, okrągłe płytki z czujnikami białej linii. Stal była cięta laserowo oraz później frezowana. Napęd robota stanowiły znane i lubiane silniczki Pololu HP z przekładnią 50:1 przykręcone bezpośrednio do podstawy za pomocą dedykowanych mocowań. Podpięte do elektroniki były przy pomocy złączy ARK co umożliwiło ich łatwy demontaż w celach serwisowych. Obudowa robota została wykonana z laminatu 1mm. Na obudowie znajduje się nazwa robota oraz nasze imiona i nazwiska. Obudowa mocowana jest do podstawy za pomocą śrub, a jej elementy są do siebie lutowane. Dach robota wykonaliśmy z 2 mm przeźroczystego szkła akrylowego. Finalnie robot mierzy w najwyzszym miejscu 33,7 milimetra od podstawy do dachu, a od podłoza do dachu 37,2. Jego podstawa ma wymiary 98,9 mm na 99,6 mm. Masa waha się od 490 do 499g w zależności jak bardzo nakarmimy robota przed zawodami Elektronika Priorytetem projektu robota była jego dobra konstrukcja mechaniczna, w wyniku czego wymiary płytki z elektroniką były z góry narzucone. Elektronika została zaprojektowana w programie KiCad po zaimportowaniu wymiarów przeznaczonych na nią z programu Inventor. Elektronika robota dzieli się na dwie płytki: główną, która znajduje się tuż nad podstawą robota oraz dodatkowej, na której umieściliśmy włącznik zasilania, interfejs komunikacyjny oraz złącze na moduł startowy. Płytki połączone zostały ze sobą taśmą FFC. Mała płytka widoczna na zdjęciu nad płytką główną służy nam jako podstawka pod akumulator LiPo 7.4V, którym zasilamy robota. Sercem naszego robota został mikroprocesor STM32F1. Wybór tej rodziny wynikał z łatwości ich programowania przez początkujących. Czujniki odległości wykorzystane w robocie to znane i lubiane cyfrowe Sharpy 40cm. Umieściliśmy je 4, dwa z przodu oraz po jednym na bokach. Na czujniki białej linii użyliśmy dwa KTIRy 0711S. Jak wcześniej wspomniałem zostały one umieszczone na małych płytkach, które umieściliśmy w wycięciach w podstawie. Na sterowniki silników wybraliśmy dwa, podwójne mostki H TB6612. Zostały one dobrane ze względu na ich dobrą wydajność prądową, co umożliwiło nam skuteczne wysterowanie silników Pololu bez obawy o to, że przy pełnym zwarciu mostki ulegną uszkodzeniu. Płytki zostały wykonane metodą termotransferu oraz wyfrezowane za pomocą Dremela i pilników ręcznych. Software Kod robota został napisany w środowisku System Workbench for STM32 (SW4STM32) z użyciem generatora kodu konfiguracyjnego STM32CubeMX. Program podzielony był na dwie sekwencje: startową i walki. W pierwszej ustawiana była konfiguracja algorytmu robota oraz dostępne były funkcje testu czujników (widoczny na zdjęciu poniżej - cztery czerwone diody, które odpowiadały za pokazanie aktualnego stanu czujników) oraz czyszczenia kół (drobna funkcja pomocnicza ustawiająca małą prędkość na kołach). Sekwencja walki załączała się po otrzymaniu przez robota sygnału startowego z modułu. Większa część algorytmu walki opierała się na prostych if-ach z odpowiednio dobranymi nastawami silników w każdym przypadku, co okazało się wystarczające w większości starć. Następnie zostały dodane pewne udoskonalenia, o których już rozpisywać się nie będę Osiągnięcia - II miejsce Robomaticon 2016 - I miejsce Robotic Tournament 2016 - III miejsce Festiwal Robotyki Cyberbot 2016 - II miejsce [Minisumo] oraz I miejsce [Minisumo Deathmatch] Trójmiejski Turniej Robotów 2016 - II miejsce Opolski Festiwal Robotów 2016 - I miejsce Robotic Day 2016 [Praga] A poniżej kilka filmów z udziałem robota: 2Weak4U vs Hellfire 2Weak4U w Wiedniu 2Weak4U vs Dzik 2Weak4U vs Shevron (chyba) 2Weak4U w Deatmatchu [Rzeszów] 2Weak4U vs Szwagier Pozdrawiam i do zobaczenia w następnym sezonie, Aleksander
  25. ozkam

    Bolt

    Witajcie! Bolt to robot klasy Linefollower Standard. Został zaprojektowany, zbudowany oraz zaprogramowany przez kolegę Hubert.M oraz mnie. Jest on naszą najnowszą konstrukcją. Konstrukcja mechaniczna. Robot składa się z 2 płytek PCB, wykonanych przez firmę SATLAND Prototype. Płytki połączone są dwiema węglowymi listewkami, a z tyłu robota znajduje się aluminiowa podpórka zabezpieczająca przed przewróceniem się robota. Podpórkami listwy czujników są tranzystory w obudowie TO92. Silniki użyte w robocie to popularne Pololu HP 10:1. Koła wykonał dla nas hungrydevil. Masa robota z baterią wynosi 69 gramów. Elektronika. Zdecydowaliśmy się na mikrokontroler STM32F103C8T6. Silniki sterowane są układem TB6612. Zastosowane czujniki linii to KTIR0711. Czujników na chwilę obecną jest 9. Zastosowaliśmy moduł bluetooth HC-05. Zastosowanie modułu znacznie ułatwiło strojenie robota. Ponadto stan każdego czujnika jest odzwierciedlony diodą LED. Robot zasilany jest pakietem Li-pol o pojemności 150mAh. Część logiczna robota zasilana jest napięciem 3.3V. Program. Algorytm robota jest napisany w języku C. Zastosowano regulator PD. Dzięki modułowi BT wszystkie nastawy regulatora mogą być ustawiane bez ponownego programowania robota. Ponadto, program pozwala na np. zdalne sterowanie robota po połączeniu z komputerem. Do zażądania robotem napisaliśmy 2 aplikacje – na telefony z systemem android, aplikacja pozwala na wystartowanie robota, a także na jego zatrzymanie. Z Kolei aplikacja na PC oprócz podstawowej funkcjonalności pozwala na dobieranie nastaw robota. Ponadto można za jej pomocą rysować wykresy uchybu i pochodnej z uchybu. Bolt ma brata bliźniaka, o nazwie Bez Nazwy. Jest on nieco szybszy od Bolta (bo czerwony). Osiągnięcia i plany na przyszłość. - 2 miejsce na Konkursie robotów SEP Gdańsk 2015 - 4 miejsce na SUMO Challenge 2015 W robocie planujemy jeszcze bardziej poprawić jakość sterowania, oraz rozważamy wykonanie węższej listwy czujników z czujnikiem odległości, aby móc startować w kategorii LF Enhanced. Film z przejazdu:
×