Welcome, Guest
Username: Password: Secret Key Remember me

TOPIC: Pi Zero Wifi / STM32F103CBT6 Project Node Servers

Pi Zero Wifi / STM32F103CBT6 Project Node Servers 3 months 1 week ago #17948

  • hop
  • hop's Avatar
  • Offline
  • Platinum Boarder
  • Posts: 400
  • Thanks received: 45
I have been playing with some Raspberry Pi Zero Wifi modules and I have done some neat things with them. Now it is time to put them to use. I am using a heirarchy of sorts. RPI0W (Raspberry Pi Zero Wifi) at the top with a blue pill STM32F103CBT6 to assist. These two devices will be talking to each other and housed in an empty anti-persperant container. The blue pill will control an OLED 128x64 display that is mounted in the lid.

The RPI0W node server hosts are fitted with a 32gb class 10 micro SD, running Debian Raspbian with light database and web server support. I will be writing python scripts that will run as cron jobs or web interface triggered to handle data recording and control for a variety of slave devices connected through the blue pill. These slave devices will be drones and consist of pro-mini's, other blue pills, and boards I design on my own. They will function as sensor and control interfaces but will also contain autonomous functioning code in case the host node server is offline. Then they can cache whatever data they can until the node server comes back online.

Each slave device on these little networks will be communicating via I2C hopefully, or down-scaled to ASCII serial USART commands if needed.

I already have one of the node servers recording my morning radio shows (streaming) as a back up to the home server. It works great!!!

The screens on the node server OLED's will follow a set format, but will be configured to show server health, internal temps, device connections, and status messages related to the connected project.

Each node server will oversee a project. Hydroponics, accent lighting in a room of the home, security, whatever.

More is definitely coming on this project. I am so excited!!!

Pi Zero Wifi / STM32F103CBT6 Project Node Servers 3 months 1 week ago #17949

  • hop
  • hop's Avatar
  • Offline
  • Platinum Boarder
  • Posts: 400
  • Thanks received: 45
First on the list of work to do on this project is to get a lot more familiar with the STM32 line of microcontrollers, specifically, the STM32F103C8T6. This device uses the ARM 32-bit Cortex-M3 CPU Core, runs at 72 MHz, has either 64k or 128k flash memory (yet to be determined by me, much debated, and it's on my list), and 20k SRAM. It also has a wealth of peripherals including 3 USARTs, USB (2.0), CAN, SPI, I2C, 7 Timers, 2-12 bit ADC's, CRC, and these are just the features that interested me. There are a few more toys.

Anyway, my faith in this processor has already been vindicated a few times over, and you would have to buy a thousand of them from Mouser just to get the price to $3.20. Yet I was able to buy 20 blue pill (MAPLE?) boards for $1.97 apiece through Aliexpress in 2 lots of 10. That price is amazing for this level of boarded tech!!

As far as programming this little gem, I was stumped at first. I did not know about STLINK yet though, and after getting a few discovery boards with STLINK on-board, I discovered that using that interface to program my "Blue Pills" works wonderfully! Not only that, the 4 wire interface allows for full debugging. YAY!

But as I moved past just blinking an LED, I quickly realized the short-falls of using Ardiuno hand-holding. As a matter of fact, with the plug-in into Eclipse, it becomes the safety of a hand-holding adventure along with the hazards of malfunction. You post about the bugs only to get solicited for donations and excuses about how there is no time to address every issue. I would throw errors compiling, tab out to research, and go back to do it again without changing anything and it would work. Not the stability I was hoping for. And there is peripheral support short-falls... like I2C slave support not supported yet in the libraries.

All that seems to be swept away now though. I found a new platform that is working great for me. It is a lot more involved though, with a greater knowledge of the libraries and devices almost a prerequisite, but with the right approach to chasing down issues, the results are awesome! What I am talking about is STLINK+CUBEMX+KEIL and I am loving the IDE and the solid error-free reliability.

There is a process though to setting up a project, and after repetition, it will become easier. I am FURIOUSLY working to get that as simple as possible for anyone that is interested. It is one thing to have the intuition and see what is wrong, but for someone new that does not understand the implications, a good tutorial that shows them the ropes is paramount. Especially for ME! :woohoo:

I have been playing in the Linux swimming pool for a long time, so the RPI0W (Raspberry Pi Zero Wifi) part of this system is not a concern for me. It's her assistant manager so-to-speak, the STM32F103C8T6 I picked to watch over her, delegate, and manage the middle link. And yes, the assistant is necessary. More on that later.

So my list of R and D is simple. I outlined several topics for completion with the STM32, then I can put it together and move on to the drone devices, and the captain that manages them through this STM32.

That's where I am today. More when I do it. Thanks for listening!!

Pi Zero Wifi / STM32F103CBT6 Project Node Servers 3 months 5 days ago #17950

  • hop
  • hop's Avatar
  • Offline
  • Platinum Boarder
  • Posts: 400
  • Thanks received: 45
I am so pleased with the KEIL+CUBEMX+STLINK development system for the STM32. There are actually many other chip vendors supported by CubeMX, not just the STM32 line. They updated it 28 times since version 4.0 and it keeps getting better.

One thing to note to anyone that goes after using this trio. If you use CubeMX especially, you can use it again and again for existing projects, to add peripherals and change their initialization parameters, and it will update the MAIN.C with the new code, leaving your existing custom code alone!! WOW! But you absolutely have to remember to code within the lines. I cannot stress this enough....

I was chasing my tail this morning that almost led to a post for help on the STM32 forums when I noticed my LED blink out of the corner of my eye. The flash rate was MUCH slower and I incorrectly diagnosed the problem thinking I messed up the Timer 2 interrupts and/or the ISR when I enabled USART3. Fact is, they can be used as I intended simultaneously. The problem was that I changed the period value for timer 2 in the initialization code to the value I wanted. I had already set it to a much higher value in CubeMX though, and when I went back to CubeMX to enable USART3 and re-generated my code, the initialization code for Timer 2 was set back to that higher value. And because I use counter variables in my ISR, the flash of my LED was MUCH SLOWER.

So stay within the user commented lines. It is pretty simple because CubeMX writes a lot of comments for you to follow.

One neat feature I am checking out this morning... in CubeMX, when dealing with the peripherals, there is the option to add user constants. This would allow you to change the values without having to do all that in CubeMX.

Notice the various USER CODE BEGIN {xxxx} sections. No, I do not fully understand the stages (0,1,2,3,4) yet. Notice further down with the timer section.
htim2.Instance = TIM2;
  htim2.Init.Prescaler = 35999;  // CHANGE THESE VALUES IN CUBEMX!!!
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 10;    // CHANGE THESE VALUES IN CUBEMX!!!
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

This is NOT in a USER BEGIN / USER END block so it was rewritten by CubeMX.
int main(void)
{

  /* USER CODE BEGIN 1 */
      // OK in here
  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */
      // OK in here
  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */
      // OK in here
  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM2_Init();
  MX_USART3_UART_Init();

  /* USER CODE BEGIN 2 */
	// initialize timer
		HAL_TIM_Base_Start_IT(&htim2);
		
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
	char buff[50] = "HopWorks STM32 NODE SERVER SUPPORT SYSTEM \n\r";
	HAL_UART_Transmit(&huart3,buff,strlen(buff),1000);

  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;

    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  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_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != 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);
}

/* TIM2 init function */
static void MX_TIM2_Init(void)
{

  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;

  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 35999;  // CHANGE THESE VALUES IN CUBEMX!!!
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 10;    // CHANGE THESE VALUES IN CUBEMX!!!
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

Pi Zero Wifi / STM32F103CBT6 Project Node Servers 2 months 3 weeks ago #17954

  • hop
  • hop's Avatar
  • Offline
  • Platinum Boarder
  • Posts: 400
  • Thanks received: 45
Wow these baby steps I have had to take with this development system has been more like the first 30 minutes of a Thomson's Gazelle's life in the Serengeti. Now that I have buffed out the rough spots, learned to run so to speak (to avoid being dinner), I finally achieved my goal of having the STM32F103 control a SSD1306 128x64 display. It was not easy, certainly not as easy as getting the display to work with the RPI Zero, and I chased my tail for days figuring out how to implement the U8G library for ARM, but it is working finally!!

Along the way, I also figured out the USART, hardware timers, and interrupt handling. There is SO MUCH to write about now!

First of all, the OLED display was not working with the "Blue Pill". My Blue Pills are Maple clones, a development board that hosts the STM32F103C8T6 ARM Cortex 3 processor. I can get them in lots of 10 through AliExpress for a little less than $2 a board. I can program them via SWD using the ST-LINK V2.1 built into my Nucleo discovery boards. Anyway, I brought my Rigol 1054Z scope into it to look at the SPI signals and even though I was unable to decode the data, I could see the signal lines activity so I know it was working. It turned out to be the RES line of the OLED display. It has to be tied to VCC (3.3v) to allow operation. Just tieing it to VCC was not enough though and I will elaborate a bit further down.

Maybe it is just assumed, or maybe there is a document out there about the U8G library related to this, but in KEIL, it is not just enough to include the u8g.h header file. You have to add all the related C files to the project in order for it to work. Not all the files are necessary, so I had to compile, see the errors, search the C files for the functions, and add them one by one until I could compile without errors. I am working on a fork of this ARM version of the library that is a bit easier to add and use.

Then there are a fonts. u8g_font_data.c has a TON of hard-coded fonts to use. Some are small, some are a bit larger. You need to decide what worked for whatever you are doing. When I found the fonts I wanted to use, I had to create my own header file to declare them using EXTERN.

So now all that is left for this part of the project is to write the communications routines to talk to the children systems and the node server. I want to do this with I2C, but for now, it is going to have to be USART text messages.

There is so much to do after this is done. Python access through a web interface, cron jobs, a frame work for all of that, and then offline redundancy.

A big hurdle was breached today though, and the project is progressing on. YAY!

I will try to find time to write this up soon. Stay tuned!!

EDIT: I had to implement a toggle of the RES line for the display. I picked PC11 on the board (Port C, pin 11) from low to high with a delay. The reason for this is because the display showed garbage most of the time when the board was powered up. Now that I put this support into the INIT code, it always shows the desired results.
Last Edit: 2 months 3 weeks ago by hop. Reason: Afterthought

Pi Zero Wifi / STM32F103CBT6 Project Node Servers 2 months 2 weeks ago #17955

  • hop
  • hop's Avatar
  • Offline
  • Platinum Boarder
  • Posts: 400
  • Thanks received: 45
Raspberry Pi Zero Wifi - USART TROUBLE

My system's inter-processor communications scheme took a turn for the worst when I was unable to solve the poor USART performance of the Raspberry Pi Zero Wifi. Apparently, the main USART was routed to the blue tooth functions and a software mini-usart was routed to the serial GPIO. There is an overlay that supposedly routes the main USART back to the serial GPIO, but all my attempts to stabilize that communication has failed.

Serial USART was suppose to be a simple fix for me anyway, avoiding having to wire the system to use I2C because the STM32F103C8T6 libraries do not support hardware I2C in slave mode yet. I was just being lazy though. And in the Arizona White Mountains with my mobile setup, without my scope, I decided to wait until I got home to try it.

I2C suits my purposes here just fine, but I wonder if there is another multi-processor communications protocol that is much faster? SPI seems wrong for a master with multiple slaves, and not sure how 1-wire would be implemented. I am open for suggestions.

Pi Zero Wifi / STM32F103CBT6 Project Node Servers 1 month 3 weeks ago #17960

  • hop
  • hop's Avatar
  • Offline
  • Platinum Boarder
  • Posts: 400
  • Thanks received: 45
OK, the ball is rolling forward again! YAY! I was able to talk to between two development boards, the STM32F411E-DISCO using I2C, with one as a slave and the other as the master. It was very effective even at higher speeds.

Then came the process of porting the example code over to the STM32F103C8T6. So far so good but still in that process. I would be DONE by now, but the examples available in the Keil packs has setup code that is generated by something other than STM32CubeMX. Because of this, it has a been a little harder, but I think I almost have this part done. When I can get the STM32F103 to receive and send back data as a slave to the STM32F411E-DISCO setup as a master, I will be ready to move to the RPI Zero WiFi as the master. Then I will use python to talk to the STM32F103.

WHEW!

All of this has helped me to edge up and climb slightly over the learning curve of this development platform.

MORE when I code it! I think I mentioned it, but I was able to get the STM32F103 to talk to my SPI OLED 128x64 display. Now I can use that to show me messages via the I2C buss. WOOHOO!!!


Time to create page: 0.247 seconds