- 10
- 126 897
Random Rick
United Kingdom
เข้าร่วมเมื่อ 3 ก.พ. 2014
Leccy engineer with way too much experience and the grey hairs to prove it! These videos are mostly "notes to self" reminders of stuff I found out and don't want to have to re-learn in the future. Mostly...
Common Emitter Amplifier - Analysis and Design
This is (I hope) a fairly simple guide on how common-emitter amplifiers work, and how to design one for the gain and voltage swing you want. No base currents, betas or bandwidths - just the minimum to understand and design these things!
Literally no expense spent on fancy graphics or design. I hope you can forgive me.
Literally no expense spent on fancy graphics or design. I hope you can forgive me.
มุมมอง: 568
วีดีโอ
STM32 PWM basics
มุมมอง 21K2 ปีที่แล้ว
See how to create a very simple PWM output on an STM32 microcontroller. I try to keep my examples simple so that it's easy to see what's necessary and no more. After showing how to set up and control a PWM output, I go on to show how to set up interrupts on the PWM edges as well, if desired. Code: github.com/RandomRickStm32Experiments/pwm_demo
stm32 timed multichannel ADC DMA conversions on STM32F030k6
มุมมอง 18K2 ปีที่แล้ว
Yet another "note to future self" video about STM32 DMA ADC acquisition. This time, multiple channels are being sampled into a buffer, triggered by a TIM1 event, rather than by repetitive software calls. This way, the ADC subsystem does its thing in the background and your code can react when it's ready. Sorry for the ghastly video and audio production values. I'm not a pro.
STM32 Timer-based ADC sampling at a specific rate, with debug output
มุมมอง 21K3 ปีที่แล้ว
How to set up an STM32 to sample an ADC input at a specific rate, with a timer generating "events" that automatically perform the next ADC acquisition. You'll see in the code that there's no timer ISR used to kick off each conversion - it's all automatic until the DMA buffer is full.
Set up multiple ADCs on STM32 microcontrollers using DMA
มุมมอง 39K3 ปีที่แล้ว
Just a little note-to-future-self video, showing how to set up multiple channels on an STM32 ADC, and use scanning to read those ADCs. DMA is set up to record the values to RAM. This demo uses the STM32CubeIDE development environment, and uses the HAL library, not the LL libs.
STM32 Stepper Motor Control with a smoothed FIR response
มุมมอง 5923 ปีที่แล้ว
A little demo of my stepper motor control with joystick input.
SMT32 ADC Interrupts with STM32CubeIDE
มุมมอง 13K3 ปีที่แล้ว
This is a minimal project to get ADC interrupts working on an STM32 Nucleo F303K8 board. Using interrupts means that your code doesn't have to sit around polling the ADC to see if it's ready - that's all taken care of in the interrupt callback function. I've deliberately kept the video to doing little more than triggering ADC conversions and printing them to the UART - these videos can get conf...
Microchip MPLAB X IDE: How to set the font size
มุมมอง 4.2K3 ปีที่แล้ว
You can set the font size of the editor window from within the IDE, but setting the font size of other windows and menus takes a little work. This short video shows how to do that.
Use Nuget to install MySQL Connector/NET on Visual Studio
มุมมอง 6K4 ปีที่แล้ว
A quick tutorial, as per the title
NowTV router firewall setup
มุมมอง 3.5K4 ปีที่แล้ว
A quick video on how I set up my NowTV router to allow NodeRed requests from the outside world through the firewall and into my local network.
Thank you so much it does work !!
greetings me lmao
Why does it feel like I can't breath listening to you speak? It's like you're talking while out of air and silent when you actually breathed. LMAO. Is this just the English way of speaking?
Hi Rick, thank you for the useful video. Can I clarify one thing? I’m fairly new to programming STM32s. The yellow trace on the oscilloscope (channel 1) is generated by the GPIO toggle in the HAL_ADC_ConvCpltCallback(…), right?
I'm still a beginner on this area but thank you for this valuable video! Can I have a question? Do you know how many PWM waves that I can generate from 1 STM32 MCU? And the frequency range that it can generate..? Thanks... and sorry for the beginner question..
*Summary* *Goal:* (Starts at 0:00) * Sample an ADC input at a specific rate (40kHz in the example) using an STM32F303K8 microcontroller. * Use timer events to automatically trigger ADC conversions, eliminating the need for software-triggered conversions. * Provide a debug output signal synchronized with the ADC sampling rate. *ADC Setup:* (Starts at 1:16) * *Disable Scan Conversion Mode:* Ensures that only a single ADC channel is sampled. * *Disable Continuous Conversion Mode:* Prevents continuous ADC conversions; conversions will be triggered by the timer. * *Set External Trigger Conversion Source:* Select the timer output event that will trigger the ADC conversions (Timer 1 Trigger Out Event in this case). * *Configure Trigger Polarity:* Choose whether the ADC conversion should be triggered on the rising edge, falling edge, or both edges of the timer output. *Timer Setup:* (Starts at 3:05) * *Select Internal Clock Source:* Use the internal clock to drive the timer. * *Configure Timer Period (ARR Register):* Set the timer period to achieve the desired ADC sampling rate. The example uses a period of 1000 clock cycles for a 40kHz sampling rate with a 40MHz clock. * *Enable Update Event Generation:* This event is triggered when the timer counter resets, which will be used to trigger the ADC conversions. * *Configure Output Compare Channel (Optional):* This can be used to generate a debug output signal synchronized with the ADC sampling rate. The example configures Output Compare Channel 1 to toggle on every timer counter reset, generating a square wave at the sampling frequency. *Software Implementation:* (Starts at ~5:22 - not explicitly stated but code walkthrough begins) * *Initialize Timer and ADC:* Set up the timer and ADC peripherals with the desired configurations. * *Start Timer and Output Compare (if used):* Enable the timer and output compare channel to begin generating trigger events and debug output. * *Start ADC DMA:* Configure and enable DMA to transfer ADC conversion data to a memory buffer. * *Handle DMA Conversion Complete Callback:* This callback function is called when the DMA buffer is full. It can be used to process the acquired ADC data and restart the DMA transfer for the next buffer. *Key Points:* * The code leverages hardware features (timers and DMA) to automate the ADC sampling process, minimizing software overhead. * No interrupt service routines are required for ADC conversions. * A debug output signal allows for visual verification of the sampling rate. i used gemini 1.5 pro to summarize the transcript.
did you try this for more than 1 channel?
Nice Video. Thanks for uploading
Middle light won't go green
This is very interesting. Thank you
Thank you for this tutorial. But I am still wondering about this code HAL_ADC_Start_DMA(&hadc, (uint32_t*)AdcResults, sizeof(AdcResults)/sizeof(AdcResults[0])); I have used DMA but I did not quite understand the sizeof(...)/Sizeof(...) meaning. i would be grateful help me out.
Hi, I will try to answer you, it is about what is HAL_ADC_Start_DMA is waiting for and what are you telling with sizeof(). - sizeof(AdcResults): returns size of the array in bytes. If AdcResults is an array of 3 elements of type uint16_t, the size will be 3* sizeof(uint16_t), which is usually 3* 2 = 6 bytes. - sizeof(AdcResults) / sizeof(AdcResults[0]): This returns the number of elements in the array. In this case, it will be 6 / 2 = 3 elements. (Adcresults[0] has 2 bytes as it is type uint16_t) HAL_ADC_Start_DMA is waiting for the number of elements of the array. So if you give it with the first way it may cause malfuctions in your code. I hope it helped you to figure it out.
@@lookatravieso5036 thank you very much. It is very helpful.
Thanks for making this video. I have to go back to it every time I migrate my project to a different chip and set everything up all over again. It would be nice if STM32cubeIDE would just let you select a different chip, and highlight issues that need to be solved manually.
You use volatile to tell the compiler the variable is used (updated) outside of the routines that reference it; in this case, the DMA writes to it. You need to change the title of your presentation to Set up multiple channels of a ADC for scan using DMA. This is important because was looking for setting up multiple ADCs (ie. ADC 1, ADC2, ADC3) all using scanning. Since there is only one callback I need to know how to tell which ADC DMA was completed.
Dear sir thank you for your valuable viode, can you share with me what application you had used for PWm signal display?
Thanks for the compliment. The application is called Ultrascope, and it comes from Rigol and works only with their oscilloscopes. If you don't already have a scope, there are much better options for viewing signals on a PC. Owon do a USB oscilloscope that's cheap and has much faster update on the computer, or if money is no problem, consider a PicoScope.
thanks , just im asking if i want to control the adc to make interruption at a specifiv valure let's say for example i want temperature's sensor activate the buzz at a determined degree what should i do?
I don't think you can interrupt at a specific ADC value. You will have to use the normal ADC interrupt handler to look for the value and then act when it is above your threshold value.
@@randomrickUK thanks a lot
Wow...I spent most yesterday trying to figure this one out with no luck...It worked first try after watching this! Thanks man!
You're very welcome!
How to use now tv box in Pakistan
You didn't setup multiple ADCs via DMA, rather multiple channels on single ADC. Caption is bit confusing
May feel silly but i'm new to stm32 and cube ide Why you write if(h == &hadc2)
Hi - it's because both ADC1 and ADC2 share the same callback function. Look at time 3:15 - the only choice is to enable interrupts for both ADC1 and 2. So in the callback, you need to know which ADC just interrupted, and handle them separately. Of course, if you're only using one of those two ADCs, then there's no need to check.
please help me i am doing an internship if i would be not able to generate pwm with varying duty cycle i will be get layoff please help me out .... please help me i need this job
hey @RANDOMRick i am seeing for your help
hi can i contact with you i need your help
hey i am from india can u please help me regarding pwm generation and fow to vary duty cycle for stm32f103c8t6 microcontroller
That microcontroller also has a TIM3 timer, which means you can set it up the same way I did here. Have you tried doing this? I really need a bit more detail to help you - what did work, what didn't, etc.
I got valid reading for only one channel; the other one is always 0. What could be the problem?
Hi, good night. I need to known how identify one adc channel when an interrupt is generate and several channels its in operation. Thanks in advance
AT 5.50 what does the auto-reload preload do? why it's disabled?
I believe this preload is used when ARR is being dynamically changed. It prevents strange events when the ARR register is updated at certain times. If you want a fixed period/frequency, then you won't be changing the ARR and therefore the pre-load register won't do much for you.
Thank you so much for this video! I was using low power modes and was looking for a way to trigger DMA to get ADC values but only once per sec, not in the continuous mode. Just for the sake of lower energy consumption. Couldnt get this on my own, had to enable DMA Continuous requests for it to trigger, such a small detail :/
thank you soo much this was super helpful
This is very very helpful. Thank you.
Thanks a lot bro
Did you use your own router? Does the now broadband box have a DMZ option?
the ending gave me schizophrenia
Thank you. Very informative.
I want to read 1 khz analog waveform after 50 microsecond of rising edge on adc which method of adc should i use for this
Hey man I love this :) if you made a whole STM32 tutorial in this style. I bet more people that I would love it :) great humor also btw
Thanks, Mr GameCat - much appreciated!
Can you take a video about the outputs, I could not get an output
Hi your video is really good, but I need to write these results by using usart but I don't know in which function can I write, I an writing in convcallback function,I could not see any output, I write in while it has no output also, what can I do to make it write by usart?
I could not understnd exactly, I need to sample my signal at 1000 Hz, what can I change from your code?
You need to change the settings of the timer (i.e. not the ADC). You need to set both the Prescaler (the PSC register) and the Counter Period (the ARR register) so that together they slow down the system clock to your 1000Hz (or 1 millisecond). This doesn't slow down the whole device - it just affects that timer, which is what we want. Although one part is called a prescaler and the other is called a counter, they both have the same effect of dividing down the main clock for your timer. So the timer runs at "system clock / prescaler / counter". Remember to reduce the value of both parameters by 1 due to the way the timer circuit works. For example, if you want the prescaler to be 50, then the value in the register should be 49. There is often more than one combination of Prescaler/Counter values that will give the same result. But for 1000Hz, it should be pretty easy unless you have a strange main system clock like 12.321 MHz, but you probably haven't. Let's say your system clock is 8MHz. That needs dividing (slowing) down by 8000 to get to your target of 1000Hz. Here are a couple of combinations that could do that: Prescaler 8000, Counter 1 (but that would be 7999 and 0 in the registers) Prescaler 1000, Counter 8 (999 and 7 in the registers) Be careful not to choose values that are too big for the registers! On some parts and in some timers, the Prescaler is only 16 bit, so you can't choose numbers bigger than the maximum for 16 bits. If you want to get a 1Hz pulse, you can't just put 8000000 in to the Prescaler because that number is too big.
Thank you so much, for example if I choose 10 MHz and I did not divide it(so I chose divider 0), I arranged the ARR to 999, is this divider calculation true?but I have another question, I am getting EEG signals, do not I need to use Contunious Conversion instead of single conversion?
Thank you , it worked for me , the only issue is the adc is giving wrong reading in the buffer for indexes 1, 3,5...... when i use this method and the error is fixed where i get 2920 instead of 3520 for all of them ( im using a fixed dc signal just to test which corresponds to 3520) , but when i use the normal case without timers i dont get that error , so for indexes 0,2,4.... i get correct values 3520 . any idea why this is happening ?
No, sorry, I don't have an immediate idea of what's happening here. It doesn't make sense to me that only certain ADC acquisitions would give the wrong ADC reading. I'd really have to see both the code and the circuit to help further with this issue. I hope you manage to find an answer.
Really useful summary! Thanks! 😁
Really useful, thanks! 👌
thanks
awesome video. How can i do this with a timer?
Thanks! You can trigger ADC conversions with an "event", and set up the timer to issues those events. I've got a video about it: th-cam.com/video/Q4I9m0kNZBI/w-d-xo.html
Clear and easy! Very helpful!
Hello Mr. as I can vary the duty cycle on a variable in real time without using a potentiometer ?
Hi - yes, for sure. You can just set the register (TIM3->CCR1 in my example) to any value between 0 and TIM3->ARR. You can do this anywhere in your code that you wish - it doesn't have to be before you start the PWM output, and you can do it as often as you need to.
@@randomrickUK thank you very much for your availability i did this but the problem is that the value can not be changed in real time. to change the value you have to load it and recompile the program again
@@abdoulayebodian3583 Are you sure your code is being executed? In my video, near the end, you can see how I dynamically change the duty cycle. I put it in an interrupt callback, but you don't have to do that. It could go in the while (1) loop in main: while (1) { TIM3->CCR1++; if (TIM3->CCR1 == TIM3->ARR+1) TIM3->CCR1 = 0; // go back to 0% duty when 100% reached HAL_Delay(100); } something like that.
@@randomrickUK tank you
You absolutely saved me, I have been trying to get into STM32 and could not get it to work. Finally I found this masterpiece. Thanks a lot!
Thanks for the kind comment !
hey i am from india, can u please help me regarding pwm generation and how to vary duty cycle for stm32f103c8t6 microcontroller
hi can i contact with you i need your help
thankyou so much
Such a clear explanation. Great video! Hope you make more videos like this.
Thank for you jobm it was good
Hi I'm quite new at this and I got stuck and need some help. Creating the tx buffer gives me a compiler failure, did I forget to include something?
Hi Johan. First thing to check is the automatically generated code. Near the beginning of main() in main.c you will find the calls to the initialisation functions. Check that the call to MX_DMA_Init() comes BEFORE the call to MX_ADC_Init(). Sometimes CubeIDE gets this wrong, and you have to manually edit it. Though of course if you re-run the code generator, it will overwrite your change and you'll have to re-apply it.
@@randomrickUK Hi I got everything working except the dma buffer variables, the compiler just wont accept these ones: uint16_t dmaBuffer[DMABUFLEN]; char txBuf[TXBUFLEN]; So could you please help me out with those aswell?
@@johansvensson6542 Do you mean the compiler complains about the 2 lines of code you showed me? Or their use somewhere else? It looks to me like one buffer is for ADC and the other is for UART but I don't know if you're using DMA for both or just for the ADC. Have you declared (#define) DMABUFLEN and TXBUFLEN? If so, tell me what the error message is that you're getting from the compiler, and then maybe I can help. Or do you mean that it compiles OK but just doesn't work when you run your code?
Hi, do you have a public GitHub?