Tag Archives: MCU

328P PORT MANIPULATION

#122 ATMEGA 328P Port Manipulation

Port manipulation was not important to me when I started working with microcontrollers, in fact I didn’t even know it existed and never felt the need for it especially after programming mostly in java script and PHP using functions like digitalread(pin); or digitalwrite(pin); etc. was second nature and speed or efficiency considerations were not really necessary or thought about that much.

Then after intermittently playing around with embedded ICs I got serious during the corruption virus of 2019 during lockdowns and other dilemmas while a lot of corrupt and diabolical cronies enriched themselves. I had a lot of time to focus on a few different things. There was no way I was going to let the circumstances get to me I made sure I was achieving at least one big goal each year and not get bogged down.

I took a look at the IC market and even though there was a chip shortage there were some IC’s available. This mad me try and get into efficient code and cost per IC. I came to the conclusion that I could get hold of IC’s with low memory + flash and very affordable prices. However in order to use them I would have to learn to use port manipulation, macros and interrupts in very efficient ways to the best of my ability at the time.

Now I needed to find new and comprehensive writeups of the principal and so I found the SpenceKonde
megaTinyCore
for the new at the time tinyAVR 0/1/2-series IC’s. The core has a lot explained over the years and was very helpful and easy enough to understand but took a bit of time and real world practical implementations which made learning way more fun and easy. I always need to do practical with theory when it comes to learning I find it very hard to picture learning anything without using it practically.

Now this is about port manipulation on the 328P and I’ll get into the actual implementation now without further ado.

The ATMEGA 328P has 3 ports namely B, C, D with B (digital pin 8 to 13), C (Analog input pins) and D (digital pins 0 to 7).

For the basics you only need to understand 3 types of registers you will be manipulating.

For example:

Port B
PORTBMaps to Arduino digital pins 0 to 7 Data Register – read/write
DDRBThe Port B Data Direction Register – read/write
PINBThe Port B Input Pins Register – read only

Port C
PORTCMaps to Arduino digital pins 8 to 7 Data Register – read/write
DDRC The Port C Data Direction Register – read/write
PINCThe Port C Input Pins Register – read only

Port D
PORTDMaps to Arduino digital pins 14 to 19 Data Register – read/write
DDRDThe Port D Data Direction Register – read/write
PINDThe Port D Input Pins Register – read only

So an example using DDRD (Data Direction Register) to set input and output pins:

Another example is to set digital pins 7,5,3 high:

Now you can do port manipulation with a bit shift instead of binary or hex. this makes things a bit more readable… excuse the pun. 🙂

For example to set the input or output of a single pin you could use:

Example using hexadecimal:

Now to initiate a pullup on a single pin you could use:

Example using hexadecimal:

Example using binary:

Looking at how to read a pin you can use the Input Pins Register PINB:

it is also possible to toggle a pin and there’s different ways. Some are faster then others:

You can also easily write to a pin low or high:

There’s also an atomic operation to writing low or high:

So now that we understand the basics we can get into making life easy by creating macros

Below are 4 functions made easy to iterate over all the pins in each port B, C, D

set_PIN_HIGH(pin);
set_PIN_LOW(pin);
read_PIN_STATE(pin);
toggle_PIN_STATE(pin);

This makes it easy to call the function without having to define the port each time and it’s still fast.

See the example below:

Links:

MAKING A DIY PIR SENSOR

#121 Making a DIY PIR sensor on protoboard

Front of PCB on proto board

A few years ago I wanted to use some type of sensor for security purposes in my workshop.
I just needed something to sense movement and send a radio signal to my Roboguard device.
An actual Roboguard beam was too expensive, too bulky and large and was not rechargeable… not to mention a bit overkill for my application.

So I decided to look for a low power and small sized PIR sensor. Eventually I was able to find an affordable and small PIR sensor that can operate at 3.3V. I found the MH-SR602 PIR sensor which offers an adjustable delay time with a detection distance of 0 – 3.5 Metres. it has a built in regulator with a range of 3.3 – 15VDC but adds a bit of extra current draw… since I was already using 3.3V for my IC and RF circuits I was able to de-solder the included regulator to save a bit of current. This would help me greatly especially since I was going to use deep sleep.

PCB inside the box I designed it for.
Lid closed only the PIR sensor is sticking out (Radar does not have this problem)

Now the main MCU is the ATTiny212 and the RF module used is the WL102-341… not sure on the authenticity of the module but it works range is good and the current draw is up to spec + the EN pin does disable the unnecessary current draw when pulled low. The LDO regulator I used is the classic HT7333-A.

After soldering everything and checking for shorts I was able to program the MCU and then power up the device with an recycled 550mAh vape battery. First thing I noticed the device would constantly trigger the PIR. Eventually after a long time of troubleshooting I replaced one of the ceramic capacitors used to stabilize the output of the HT7333-A and now everything worked… Now when looking at the capacitor I didn’t understand exactly why it was not working, there was no short only a really high resistance and the capacity was a bit higher than the specified uf.

Before hand I made sure the PCB would fit into a standard rectangular project box. I just needed to drill a hole for the PIR sensor to stick out. After drilling a hole for the micro USB charging port the project was complete and working.

While testing I was able to achieve a very low current draw in deep sleep mode. I did some basic calculations and the MCU should last more then a year without needing a charge. Later after leaving the device in my workshop I was able to confirm this with the device lasting over a year and a half with mild triggering whenever I was working in the workshop. making use of the ATtiny PIT for long sleep timing and interrupts for waking up the device after some code refactoring I was able to make things super efficient. I programmed everything in C. ASMM is a bit to much for low level stuff in my opinion though I would like to make time to learn it one day. Still I was able to create a program of 956 bytes using ram of 18 bytes. So under 1k was nice since the smallest ATtiny size is 2k so I’ve still got plenty of space.

Current when the MCU is in sleep mode (the PIR is always running) 121.9uA roundabouts
772.2uA of current when the MCU is running but RF is not TX’ing
13.1mA during TX

One thing I can say for sure is that this project really activated a habit in me to try make everything as small and as efficient as possible whenever I program 8-bit microcontrollers for my personal projects. I must say I was also able to save some money when buying IC’s by improving my code and what can I say it feels very good once a project is completed and as small and efficient as I could make it.

With that being said sometimes when using a microcontroller like the ESP8266 or ESP32 the resource abundance feels crazy but once I start populating all that space with HTML and bitmaps + other media I quickly realized that even that space can get used up very fast.

C.A Torino

Back of the protoboard

DIFFERENT PROGRAMMERS

#118 A look at different types of programmers

Different programmers for different IC’s some work with others.. some don’t

Over the years I have used different programmers for PIC,AVR,ST,ESP and WCH microcontrollers from simple FTDI TX RX programming to more advanced PICKit 5 dedicated programmers.

All the different types have their pros and cons but by far the most used by me is the cheap FTDI and serial TTL types for example programmers using the CH340, PL2303 and FT232 IC’s

Though the PL2303 is outdated there’s still many floating around and certain applications require the IC like when interfacing with old radios.

PICKit3, PICKit3.5 and the new PICKit5

With that being said you may ask why do we need a dedicated programmer? Well it depends…

Using the cheap common options I just mentioned above is good enough for a hobbyist but when you design a product you want something that’s is reliable common and has a guaranteed life span with support for the foreseeable future so that you will always have parts available for projects and the programmer.

USBasp AVR Programmer using SPI
STM Programmer


WCH-LinkE programmer can also program STM IC’s

Another big point is uniformity, dedicated programmers will usually be using parts with certain thresholds and voltages + current etc. all that data will be kept constant and accurate while a cheap programmer will most likely have a huge threshold..

A very important point is the ISP + debugging. A dedicated programmer will be able to do programming and debugging easily with a few pins. While a cheap programmer will require more pins and many times 2x programmers… 1 for debugging and 1 for programming.

BUS PIRATE can program with SPI
Arduino Nano with built in CH340 IC for serial programming
A n old DIY programmer of mine based on the CH340N IC

Dedicated programmers also have full support by the IC company as long as you have an original also they offer some really useful features like the PicKit5’s blue tooth option and stand alone programming or changing of source binaries on a phone.

All you need is the programmer and a phone is optional if you need to change things like binaries but really you can give a pickit5 to any technician and they can easily update supported IC’s without needing to mess around on a desktop/laptop computer. This is a very useful feature.

Now there also are EEPROM programmers and true universal programmers that can do EEPROMS and MCU’s like the old TL866II Plus which has a list here of all the supported IC’s. These programmers work well and allow easy access for single IC’s some can also read and write when an IC is in circuit but others require de-soldering. These programmers are usually quite large with Zif sockets.

EEPROM Programmer CH341B
Universal programmer the TL866II Plus

Now I just mentioned a few examples there is much more to talk about but I’m not going to be writing books here…