This is only a preview of the July 2021 issue of Practical Electronics. You can view 0 of the 72 pages in the full issue. Articles in this series:
|
PIC n’Mix
Mike Hibbett’s column for PIC project enlightenment and related topics
Part 6: PIC18F Development Board
W
e continue this month with
building programs to run on
our PIC18F development
board. In May’s article we built our first
test application which only turned on an
LED, just to prove things were basically
operational. This month, and over the
next few articles, we test the capabilities
of the platform by building a more functional application, with a very practical
use. More on that later.
In the weeks that followed our previous article the revision 2 PCB was
manufactured, and two complete sets of
the components from the recommended
sources ordered. You can see the kit of
parts in Fig.1 – some assembly required!
While you are free to obtain components
from any source, parts can vary in performance or physical dimensions, so it is
important to set a baseline source of parts
and validate everything fits and works.
Regarding components, we do strongly
recommend fitting sockets and header
pins. While not essential, it significantly
reduces the effort required to replace a
sensitive component should it become
damaged – and we have more than once
‘blown up’ a circuit through accidental
shorts, over-voltage or wiring errors. The
LCD, USB connector, SD Media connector and Wi-Fi interface are all options,
and they can be left for later, or at least
ordered cheaply from China with long
delivery lead times. It’s best to keep these
optional boards connected to the main
development board with headers (with
the exception of the USB connector, that
could be directly soldered) to give flexibility for the re-use of those pins for
other applications. Using sockets also
means that if you build a circuit board
for a specific project, you can temporarily pop the ICs out and re-use them.
The PCB is available from the PE PCB Service (code PNM-JUL21). Assembly follows
the usual through-hole component order.
There are no complex or unusual components to fit, nor special skills or tools
required. When ordering parts, it would be
a good time to check whether you should
purchase some useful accessory tools –
de-soldering braid, isopropyl alcohol and
a toothbrush (for cleaning the board after
soldering) are useful. Remember, the main
component distributors charge shipping
fees for ‘low-value’ orders, so now is a
good time to buy additional items.
The sequence of component assembly is not critical, but we would suggest
starting with the IC sockets, fixed-value
resistors, diodes and capacitors. Please
remember that two of the capacitors, the
10µF tantalums (C1 and C4), are polarised and must be fitted with the correct
orientation, as shown in Fig.2. Fit this
incorrectly and your board may work
for a while, then exhibit odd failures!
Proceed with fitting the LED, transistors and LM317 regulator. When soldering
the LM317 regulator, take care where you
bend the leads. If you plan to bolt the
regulator to the PCB, do that before soldering the leads. If you don’t, you will
place stress on the packaging which could
result in an early failure of the device.
Bolting the regulator down is not a necessity, but it does provide mechanical
stability and a slight improvement in heat
dissipation. In most uses, however, we
would not expect the regulator to run hot.
Make sure you trim back excess wires
after soldering, to avoid electrical shorts,
or scratches appearing on your workbench. Follow on by fitting the variable
resistors, power socket, header sockets
and header pins.
Now fit the small 32kHz crystal – leave
that component to the end because it is
delicate with thin wires that will snap
off if bent too much. Complete the board
by fitting the three ICs into their sockets,
affixing four rubber adhesive feet to the
bottom, and last but not least, admiring
your handiwork!
At this point you should check for
shorts across the voltage rails and then
run the simple application presented in
Fig.1. The Development Board parts.
Fig.2. Tantalum capacitor orientation.
Board assembly
PIC n’ Mix PIC18F
Development Board
The PCB for the PIC18F
Development Board is available
from the PE PCB Service – see the
July 2021 section.
www.electronpublishing.com/
product-category/pe-pcb-service/
44
Practical Electronics | July | 2021
0 – 6. 0 V
So l ar
p anel
5 V (r egu l ated)
So l ar
C h ar ger
D evi ce u nder test
A i r q u al i ty
se nso r
3 . 4 – 4. 2 V
L i th i u m
batter y
Our first project
Last month, we made a very simple, contrived project using the Microchip Code
Composer tool (MCC), just to check software tools had been installed correctly,
and to give the board a very basic test.
Over the next few articles we will build
a real project.
By a timely coincidence, a need came
up for a voltage monitor to help study
the performance of a solar-powered air
quality sensor currently in early design
stages. We wanted to monitor the voltage generated by the solar panel, and the
voltage on the small lithium-ion rechargeable battery used to power the sensor. At
a block diagram level, the system looks
as shown in Fig.3.
The solar panel will provide an output
of 6V DC under clear sky conditions, and
feeds a small charger module that will
deliver a charge to the lithium-ion battery, and boost the battery voltage from
3.7V typical to a regulated 5V DC output.
On a good day, the battery will be fully
charged by sunset. On a very cloudy day,
there may be only a small amount of
charge delivered to the battery. While it
would be easy to use a large battery and
Practical Electronics | July | 2021
em
+
V o l tage
si gnal
–
C o mmo n gr o u nd
Fig.3. Air-quality sensor block diagram.
the previous article to confirm everything
is well. When using the PICkit debugger, it is best to have the board powered
rather than rely on power applied from
the debugger itself.
To power the board, two options are provided. Header pins HDR1A and HDR1B
allow for wire or croc-clip connectors,
while the more robust method would be
to use a mains power supply connected
to the DC Barrel Jack socket CON1, which
has an inner positive pin. You can supply
the board with a voltage from 9V to 24V
DC, with 9V to 12V recommended to
avoid increasing the heat dissipated by
the linear regulator (IC1). The Microchip
programming interface is connected to
HDR2, with the MCLR pin aligned with
the triangle image on the PCB.
We did make one small change to the
board after assembly – the power LED
(LED2) is quite bright when using the
specified part. A 4.7kΩ resistor provided
a less distracting indication, but this is
really a personal taste decision, and does
depend on the specific LED you use. We
settled on 4.7kΩ as it was a value already
used on the design.
M o ni to r syt
Fig.4. Op amp circuit.
A D C
i np u t
Now, we have a new problem. The ADC
input pins require a voltage that has a
relatively low source impedance – 2kΩ
maximum, according to the datasheet. We
could achieve that easily enough – two
1kΩ resistors – but these resistors would
add additional, continuous drain on the
sensor’s battery of around 3mA. Given
that the sensor is a low-power device
with an average current consumption of
15mA, this would add an unacceptable
load, and invalidate our testing.
We need to add a buffer in front of the
ADC input so we can use a much higher
value resistor divider. The circuit to do
that is an op amp configured as a unitygain amplifier. The circuit we need to
construct is very simple, requiring the
addition of just four 470kΩ resistors,
two for each voltage measurement to the
op amps, configured as shown in Fig.4.
You can see our wiring setup in Fig.5.
We sacrificed a few hook-up leads here
rather than solder to the development
board’s header pins, but this is just a personal choice. The resistor divider circuit
on the solar panel and battery now add
only 5µA additional current drain from
the sensor’s power source, so will not
impact the measurements we are taking.
The unity-gain amplifier has a very low
output impedance, making it suitable for
driving the ADC input directly.
Now we understand the hardware
setup, let’s re-visit exactly what it is we
want our monitor device to do, so we have
a clear set of requirements to work with.
a large solar panel, we wanted to try a
number of setups to see if we could minimise the panel and battery sizes, while
still being able to provide power under
all weather conditions.
To do this, we decided to create a circuit
that would monitor the solar panel voltage and battery voltage, taking a reading
every five minutes. The monitor circuit
would be powered independently, store
data to an SD Media card and make the
data available through a Wi-Fi interface.
The measurements would be transmitted
over a serial link too, primarily to help
with development testing. The board
will be fitted into a test enclosure with
the solar-powered device, and then left
outdoors facing the sun. As the intent
is to leave this running for potentially
months at a time, the monitor board
will be powered from a mains DC power
supply, and a long power cable.
These requirements fit the capabilities of our development board very
well. As we are using the SD Media and
Wi-Fi interfaces, the board’s electronics
will need to be operated at 3.3V (so JP1
Project requirements
will be fitted.) We will need two ADC
At five-minute intervals, read the solar
inputs to monitor the voltages, and so
panel voltage and the battery voltage.
we will use pins RA0 and RA5, which
Output the voltages read over the
connect to ADC inputs AN0 and AN5
UART port connected to the UARTrespectively. Serial output will be on
to-USB converter IC.
the USB serial interface, which uses
Each data sample should be time
pins RB2 and RB3.
stamped.
So far so good, but a
problem becomes apparent. With the board
running at 3.3V, the analogue voltages on the
ADC inputs are limited
to between 0V and 3.3V.
Both the solar panel (6V
maximum) and the lithium-ion battery (4.2V
maximum while charging) exceed this voltage.
We will need to divide
these voltages down
before sending them to
the ADC inputs on the
processor. As we do not
have a high accuracy
requirement, a simple
‘divide-by-two’ resistor
network using standard
5% parts is appropriate. Fig.5. Wiring up the op amp interface.
45
Fig.6. Example of data graphed using freely available tools.
Write the voltages read to a text file
on the SD Media card.
As a stretch goal, record temperature
and humidity inside the enclosure at
the same time.
Provide a Wi-Fi interface so that the
monitor can be connected to an access
point and make the data available remotely, through the home network or
the Internet.
The monitor should be self-powered,
so there is no unacceptable current
drain on the system being monitored.
That’s seven simple requirements, although the Wi-Fi requirement is quite
vague, and we will leave it vague until
we understand the full capabilities of
the ESP-01 Wi-Fi interface. We would
ideally like to be able to ‘push’ our measurements to an online database and
produce a nice user-friendly graphical display accessible via the Internet,
like the graph shown in Fig.6. Should
that prove to be too challenging, a facility to be able to download the datafile
from the SD Media card over the home
network would suffice. How far we get
will depend on how simple the Internet
software tools are to use. We suspect,
Fig.7. Adding the ADC module from MCC.
46
however, that we are heading down an
interesting rabbit hole! Online tools for
receiving, storing and presenting data
from Internet connected sensors have
been growing year on year, and the services available for free or very low cost
are numerous.
Although the example project we are
creating here is specific to our particular
set of requirements shown above, the inclusion of monitoring temperature and
humidity is a general environmental
sensor requirement that can be adapted
to many uses that you may find appropriate, which is why we included it as
a requirement here.
Starting the design
With that above set of requirements, we
can start by working out what resources
we need from the processor. We will start
small by working to address the first three
requirements. The remaining ones can be
bolted on once the basic sensing setup
has been confirmed to work. Now our
software requirements are quite simple:
Two-channel ADC reading library
UART library
One-second timer, to provide a
timestamp
Five-minute timer, to trigger sample
sensing.
The application itself will be quite simple
in operation. The one second timer will
trigger an interrupt routine that will
update a 32-bit counter. The five-minute
timer will trigger an interrupt routine
that will read the two voltages, and set
a flag indicating that new data is available. The main loop of the program will
wait for the flag to be set, and when it is,
it will clear the flag and output the data
over the UART.
It really is that simple. The tricky part
is writing the ADC and UART drivers, but
this is where MCC comes to our rescue
– or at least, that’s what the marketing
department tell us. Let’s find out!
Building an application
We start in MPLAB-X by creating a project:
From the top-left menu bar, select File,
then New Project, then click Next.
Under Device, select our processor,
the PIC18F47K42, followed by Next.
Select the XC8 compiler, (v2.32 if you
have more than one installed) followed
by Next.
Now select a Project Location where
you would like your files to live, and
then go back to Project Name and give
a name of your choice – we went with
‘monitor’.
Click Finish.
At this point we have created the project files, but no source files – not even
an empty main.c – so let’s start by using
MCC to create the ADC driver, customised to our needs:
Click on the MCC icon, followed by
Save.
Click the triangle next to the ADCC
entry in the Device Resources panel,
and then click on the green plus icon,
as shown in Fig.7.
After a few seconds the main panel of
MPLAB-X will update, showing the settings page for the ADC, and also adding
an ADC section to the Pin Manager Grid
View, as shown in Fig.8.
We must now assign the two pins we
want to use as ADC inputs within the
Pin Manager dialogue. On the row ‘ANx’,
click the lock icon under pins PortA 0
and 5. The locks should change to green,
as in Fig.9.
The dialogue above the Pin Manager
view shows the basic settings for the ADC
peripheral. To make any changes here we
would really need to dive into the datasheet to understand the consequences of
any changes, but by default these initial
settings will be good enough. We can now
click the ‘Generate’ button next to the
‘Project Resources’ dialogue box to convert our mouse clicks into source code.
Practical Electronics | July | 2021
enable and disable interrupts, which we
will make use of once we implement the
timer interrupt routines.
Back on the ‘Files’ tab in the MPLABX GUI, click on ‘mcc_generated_files’ to
reveal the sub-directory contents. Here
you will find mcc.c, which contains not
only the SYSTEM_Initialise code, but
also adcc.c and adcc.h, the source files
that implement our ADC driver. Opening the header file adcc.h reveals loads
of functions, each nicely documented.
The ADCC_StartConversion function’s
description even includes exactly the code
we require, which we can almost cut and
paste into our main loop. The code we end
up with is shown in Listing 2. It converts
the ADC value to a voltage value, and outputs this data over the UART.
Note that the value returned from the
ADC is not a voltage, but an ADC code.
The ADC peripheral is a 12-bit converter,
which means it will output a code from
0 when the input voltage is 0V up to
4095 when the input voltage is 3.3V. The
software conversion to an actual voltage
value, which takes into account that the
signal presented to the ADC is half that
of the actual voltage being measured, is
handle by a single line of code:
solarPanel_volts = (solarPanel_
volts * 3.3 * 2.0) / 4095.0;
A more important thing to note is that this
program will not function as expected,
in fact not at all, for two reasons. First,
by default the printf function does not
actually print anything. By a standard
convention in embedded software development tools, the printf function does
all the formatting and conversion magic,
but it ultimately calls the putch function to send each text character out of the
processor. And again, by convention, the
default implementation of putch is an
empty function. The idea is that every
Fig.8. Configuring the ADC module.
After a few seconds a list of files generated is shown, as can
be seen in Fig.10. Clicking on the ‘Files’ tab in the top left-hand
corner of MPLAB-X will show the list of files, and we can double
click on main.c to see what’s been written for us. There are header
files and copious comments, but the key bit of code generated is
shown in Listing 1.
The SYSTEM_Initialise() call performs all the once-off chip
configuration – setting the system clock source, configuring the
ADC module, and setting pin modes to the settings we chose (or
left at default) in the MCC GUI. There is an empty while loop
where we will eventually place our application-specific code.
Notice also there are two commented-out lines of code, used to
Listing 1. main.c auto-generated source code.
void main(void)
{
// Initialize the device
SYSTEM_Initialize();
// Enable the Global Interrupts
//INTERRUPT_GlobalInterruptEnable();
// Disable the Global Interrupts
//INTERRUPT_GlobalInterruptDisable();
Fig.9. Assigning
the ADC inputs.
while (1)
{
// Add your application code
}
}
Practical Electronics | July | 2021
47
Fig.10. MCCgenerated files.
embedded platform will have its own
non-standard output hardware requirements, so it is down to us to implement
it. Fortunately, it is very simple to do
this, and MCC will help us out.
The second issue is that we have not
yet specified the oscillator configuration
of the processor, and the default configuration created by MCC assumes an
external high-frequency crystal is fitted.
Listing 2. main.c, updated with our application code.
void main(void)
{
adc_result_t solarPanel_volts_adc;
adc_result_t battery_volts_adc;
double solarPanel_volts;
double battery_volts;
// Initialize the device
SYSTEM_Initialize();
// Enable the Global Interrupts
//INTERRUPT_GlobalInterruptEnable();
// Disable the Global Interrupts
//INTERRUPT_GlobalInterruptDisable();
ADCC_Initialize();
while (1)
{
ADCC_StartConversion(channel_ANA0);
while(!ADCC_IsConversionDone());
solarPanel_volts_adc = ADCC_GetConversionResult();
solarPanel_volts = (double)solarPanel_volts_adc;
// Convert ADC value to volts, compensate for divide by 2
solarPanel_volts = (solarPanel_volts * 3.3 * 2.0) / 4095.0;
ADCC_StartConversion(channel_ANA5);
while(!ADCC_IsConversionDone());
battery_volts_adc = ADCC_GetConversionResult();
battery_volts = (double)battery_volts_adc;
// Convert ADC value to volts, compensate for divide by 2
battery_volts = (battery_volts * 3.3 * 2.0) / 4095.0;
// Print the values over the serial port
printf(“Battery voltage: %1.2f, Solar voltage: %1.2f\r\
n”,battery_volts, solarPanel_volts);
}
}
48
Let’s correct that now. In the Project
Resources dialogue, clicking on System
Module will bring up the settings dialogue, as shown in Fig.11. Under the
INTERNAL OSCILLATOR section, change:
Oscillator Select from EXTOSC to
HFINTOSC
HF Internal Clock setting to 16_MHz
The Clock Divider to 1.
Note at the top, where we are informed
that the Current System clock is now
16MHz. Not the fastest the processor can
run, but fast enough for our needs. Now
click the Generate button in the Project
Resources dialogue. In the Output tab of
MPLAB-X’s central window, you can see
that the auto-generated files have been
updated, but the changes we made have
been preserved. The MCC tool applies
some intelligence when changes are
made; it will avoid modifying or deleting hand-written code.
To finish off (hopefully – we haven’t
tried running the code yet!) let’s implement that putch function.
In the Device Resources dialogue,
double-click on UART, then click on the
green plus icon besides UART1. This
will open up the UART1 settings page.
Change the Baud Rate to 115200 (we
like fast communications!) and, under
Software Settings, click on the Redirect
STDIO to UART button. This should connect our printf function to the UART.
Finally, we need to select the pins we
will use for transmit data and receive data.
Click on the Pin Manager: Grid View tab,
scroll down until the UART1 Module is
visible, and select Port B 3 as RX1, and
Port B 2 as TX1. As some Port B pins are
by default mapped to analogue inputs, go
to the Project Resources tab, click on Pin
Module to bring up its settings page. On
the RB2 column, un-tick the Analog check
box. Click the Generate button for the final
time to create the revised source code.
With the source code revised, we can
click on the Notifications [MCC] tab to
Practical Electronics | July | 2021
view any hints offered during the source code generation. Yes, there is one important hint: ‘Selected
Tad (125.0ns) minimumTad (1.0µs). Please lower
the sampling frequency!’
It would appear that at our high clock speed, the
default clock input frequency to the ADC peripheral is too high. Choosing an ADC clock frequency
requires careful calculation when sampling quickly
varying signals, but with slowly changing voltage
sources, as we have here, we can be more relaxed,
and guess a ‘reasonable’ value. We set the Clock
value to FOSC/50, and the Acquisition Count to
1000 to give an Acquisition Time of 62.5µs – that
should be long enough with a low impedance
input signal to charge the ADC peripheral’s input
capacitor. We click Generate once more to revise
our source code, and the notification hint goes
away. We are good to go.
Running the code on the board with the debugger,
we see that output is generated over the USB serial
interface – great! Now, we can stop the debugger and
use the ‘Make and Program Device’ icon to flash the
code to our board, confirming that the code runs without a debugger to support it. At this point, we are
ready to proceed with the remaining requirements.
Approaching the design in this way has allowed
us to deal with the simpler requirements, gaining Fig.11. Setting the processor clock source.
familiarity with the MCC tool before moving onto
the more complicated integrations.
Coming up
Last, but not least, in a first for Practical Electronics, a
In the next article we will add the SD Media card and Wi-Fi
YouTube video has been produced that is a screencast of
functionality, and transfer our design to a custom board so
the steps described above. You can find it at: https://youtu.
we can combine it with the solar charging circuit that it will
be/WHZ4koDNNwU
monitor for the next few months.
FREE! Principles eTextbooks
Your best bet since MAPLIN
Hundreds of pages of full-colour images with
descriptive text and calculations. Extensive Tables of
Contents with Next and Previous page navigation.
Chock-a-Block with Stock
Visit: www.cricklewoodelectronics.com
0 2 0 8 4 5 2 0 1 6 1
Components • Audio • Video • Connectors • Cables
Arduino • Test Equipment etc, etc
Electronics
Computing
Mathematics
Mechanics
V is it o u r S h o p , C a l l o r B u y o n l in e a t :
w w w . c r ic k l ew o o d el ec t r o n ic s . c o m
0 2 0 8 4 5 2 0 1 6 1
V is it o u r s h o p a t :
4 0 - 4 2 C r ic k l ew o o d B r o a d w a y
L o n d o n N W 2 3 E T
Practical Electronics | July | 2021
Accounting
www.eptsoft.com
49
![]() ![]() |