Adafruit Picowbell Adalogger For Pico
Adafruit Picowbell Adalogger For Pico
https://learn.adafruit.com/adafruit-picowbell-adalogger-for-pico
Overview 5
Pinouts 9
• Power
• I2C Logic
• Duplicate GPIO Hole Pads
• microSD Card SPI
• SD Detect Jumper
• Coin Cell Battery Holder
• Reset Button
Assembly 11
Pico 12
• Assembly Steps
Stacking Headers 14
• Assembly Steps
Socket Headers 17
• Assembly Steps
CircuitPython Datalogging 27
• CircuitPython Microcontroller Wiring
• CircuitPython Usage
• Example Code
Arduino Datalogging 36
• Wiring
• Library Installation
• Example Code
Ding dong! Hear that? It's the PiCowbell ringing, letting you know that the new Adafrui
t PiCowbell Adalogger is in stock and ready to assist your Raspberry Pi Pico () and Pic
o W () project with handy hardware and datalogging.
The PiCowbell Adalogger is the same size and shape as a Pico and is intended to
socket underneath to make your next data logging or data reading project super easy.
Micro SD card socket? Yes! STEMMA QT / Qwiic connector for fast I2C? Indeed. Real
Time Clock with battery backup for accurate timekeeping? Of course!
1. Use the Pico Stacking Headers () if you want to be able to plug into a
breadboard or other accessory with sockets.
2. Use the Pico Socket Headers () if you want to plug directly in and have a nice
solid connection that doesn't have any poking-out-bits.
3. Use the Short Socket Headers () for a very slim but pluggable design; note that
you'll want to trim down the Pico's headers or use the short plug headers on the
Pico () to have a skinny sandwich.
4. Solder the PCB directly to the Pico headers - of course, this is very compact and
inexpensive, but you won't be able to remove the PiCowbell.
• Right angle JST SH connector for I2C / Stemma QT / Qwiic connection. Provides
3V, GND, IO4 (SDA), and IO5 (SCL).
• MicroSD card holder for adding as much storage as you could possibly want for
reading or writing. Connected to SPI pins 16, 18, 19 and card select on 17.
Optional card detect line can be connected to pin 15.
• PCF8523 Real Time Clock with CR1220 Coin cell backup for many years of
timekeeping. Set the time once using our example sketches and then you can
data-log with accurate timestamps. Uses I2C.
• Reset button- Press to restart your program.
• Many pads on the Adalogger have a duplicate hole pad next to it for solder-
jumpering.
• The ground pads have white silkscreen rectangles to easily identify.
• Gold-plated pads for easy soldering.
Does not come with a micro SD card () or a coin cell battery (http://adafru.it/380). A
CR1220 coin cell is required to use the RTC battery-backup capabilities! We don't
include one by default to make shipping easier for those abroad, but we do stock
them, so pick one up or use any CR1220 you have handy (http://adafru.it/380).
The default I2C address for the PCF8523 RTC module is 0x68.
Power
• VB (VBUS) - This is the micro-USB input voltage, connected to the micro-USB
port on the Raspberry Pi Pico. It is nominally 5V.
• VS (VSYS) - This is the main system input voltage. It can range from 1.8V to 5.5V
and is used to generate the 3.3V needed for the RP2040 and the GPIO pins.
• EN (3V3_EN) - This connects to the enable pin on the Raspberry Pi Pico, and is
pulled high (to VSYS) via a 100kΩ resistor.
• 3V - This is the 3.3V output from the Raspberry Pi Pico.
• VR (ADC_VREF) - This is the ADC power supply and reference voltage. It is
generated on the Raspberry Pi Pico by filtering the 3.3V supply. It can be used
with an external reference when ADC performance is required.
• G - This is the common ground for power and logic. All GND pins are highlighted
in white on the silk, with the exception of the ground pins on either side of the
SD card slot. They are labeled G.
The following pads on the PiCowbell Adalogger have a duplicate hole pad next to it
for solder-jumpering:
• GP0-GP11, GP20-GP22, Reset, A0-A2, VR, 3V, EN, VS and VB. Ground pins that
have a duplicate hole pad are highlighted in white on the silk.
The microSD card slot is connected to the following pins for SPI:
• MI (MISO/GP16) - This is the SPI MISO (Microcontroller In / Serial Out) pin. It's
used for the SD card to send data to the microcontroller.
• SCK (GP18) - This is the SPI clock input pin.
• MO (MOSI/GP19) - This is the SPI MOSI (Microcontroller Out / Serial In) pin. It is
used to send data from the microcontroller to the SD card.
• CS (Chip Select/GP17) - This is the chip select pin for the SD card.
SD Detect Jumper
On the back of the board, directly above GP15 and to the left of the cowbell logo on
the silk, is the SD Detect jumper. The jumper is labeled SD Det on the silk.
You can solder this jumper closed to connect the optional SD card detect line to GP15.
In the center of the PiCowbell is a holder for a CR1220 coin cell battery. Slot in a
CR1220 battery into the holder to use the PCF8523 RTC battery-backup capabilities.
Reset Button
In the center of the board, to the left of the coin cell battery holder, is the reset button.
It is labeled RST on the board silk. You can press it to restart your program.
Assembly
There are four ways to get your PiCowbell board working with your Pico. To keep
things flexible, PiCowbells do not come with headers: there's a lot of possible
configurations and we stock various headers depending on how you want to solder
and attach. Especially since you want the Pico on top, so that the BOOTSEL button
and LED are accessible.
1. Use the Pico Stacking Headers () if you want to be able to plug into a
breadboard or other accessory with sockets.
2. Use the Pico Socket Headers () if you want to plug directly into the Pico and
have a nice solid connection that doesn't have any poking-out-bits.
3. For some PiCowbells: Use the Short Socket Headers () for a very slim but
pluggable design, note that you'll want to trim down the Pico's headers or use
the short plug headers on the Pico () to have a skinny sandwich.
4. For some PiCowbells: Solder the PiCowbell directly to the standard headers
already soldered to your Pico. Of course this is very compact and inexpensive
but you won't be able to remove the PiCowbell. However, this method is not
possible for some PiCowbell variants depending on the clearance of the
components on the PiCowbell (i.e. the PiCowbell Adalogger and its coin cell
battery holder).
The next page shows how to solder standard headers onto a Pico board. The
following four pages walk you through each type of PiCowbell assembly so you can
choose the one that will work best for you!
You MUST solder all of the pins for the PiCowbell to work! Soldering only a few
pins, or not soldering at all are not sufficient!
If you're unsure about soldering up the Pico and PiCowbell, check out our FAQ on
soldering ().
Pico
Three out of four of the assembly methods included in this guide assume you have a
Raspberry Pi Pico soldered up with standard male headers in preparation for using it
(The shorty header assembly method uses short male headers on the Pico. The
soldering concept is exactly the same, but use the shorty male headers on the Pico
instead of standard ones. You can follow these instructions with the shorty headers
and you'll be set for that.)
Follow the steps below to solder the standard male headers to a Pico. The process is
the same for all flavors of Pico, such as Pico W.
Assembly Steps
For a bit more detail on the process of soldering standard male headers to a board,
check out the How to Solder Headers' Male Headers page ().
Stacking Headers
The first PiCowbell assembly method uses stacking headers, which allows you to use
a breadboard with your PiCowbell-Pico sandwich. This is super helpful when you're
This page assumes you have already soldered standard male headers to your Pico. If
you have not, please return to the Pico assembly page () and follow the steps there.
Although these pages show the PiCowbell Proto, the soldering instructions are
applicable for all PiCowbell boards.
Assembly Steps
Remember, the pins are labeled on the bottom of the Pico. In this case, that works
well because they are labeled on both sides of the PiCowbell, allowing for direct
comparison before attaching the PiCowbell to the stacking header assembly.
Socket Headers
This PiCowbell assembly method uses female socket headers on the PiCowbell to
create a standalone sandwich when attached to a Pico with standard male headers.
This page assumes you have already soldered standard male headers to your Pico. If
you have not, please return to the Pico assembly page () and follow the steps there.
Although these pages show the PiCowbell Proto, the soldering instructions are
applicable for all PiCowbell boards.
Remember, the pins are labeled on the bottom of the Pico. In this case, that works
well because they are labeled on both sides of the PiCowbell, allowing for direct
comparison before attaching the PiCowbell to the stacking header assembly.
This page assumes you have already soldered shorty male headers to your Pico. If
you have not, please return to the Pico assembly page () and follow the steps there.
The page shows how to solder standard male headers to the Pico, but the concept is
identical with the shorty headers.
Follow the steps below to solder shorty socket headers to your PiCowbell.
Although these pages show the PiCowbell Proto, the soldering instructions are
applicable for all PiCowbell boards.
Remember, the pins are labeled on the bottom of the Pico. In this case, that works
well because they are labeled on both sides of the PiCowbell, allowing for direct
comparison before attaching the Cowbell to the stacking header assembly.
Do not use too much solder when tacking the four corners! It can wick into the
female header and permanently attach the two boards!
Begin by inserting a CR1220 coin cell battery into the PiCowbell Adalogger battery
holder. Then, attach the PiCowbell to a Pico or Pico W as described in the assembly
pages. ()
CircuitPython Usage
Thankfully, we can do this in one go. In the example below, click the Download
Project Bundle button below to download the necessary libraries and the code.py file
in a zip file. Extract the contents of the zip file.
Connect your Pico + PiCowbell sandwich to your computer via a known good USB
data+power cable. Your board should show up as a thumb drive named CIRCUITPY in
your File Explorer or Finder (depending on your operating system). Copy the entire lib
folder and the code.py file to your CIRCUITPY drive.
Your CIRCUITPY/lib folder should contain the following folders and files:
• /adafruit_bus_device
• /adafruit_register
• adafruit_pcf8523.mpy
Once everything is saved to the CIRCUITPY drive, connect to the serial console () to
see the data printed out!
import time
import board
import busio
import adafruit_pcf8523
set_time = False
while True:
t = rtc.datetime
#print(t) # uncomment for debugging
The first time you run the program, you'll need to set the time
set_time = False
set_time = True
and update the time.struct_time to have the current time starting from year to
weekday . The last two entries can stay at -1
Re-run the sketch by saving and you'll see this out of the REPL:
Note the part where the program says it is Setting time to:
set_time = False
CircuitPython Datalogging
The following example code will show you how use the PiCowbell Adalogger with
CircuitPython to log data from a sensor to a file on an SD card with timestamps from
the RTC module. In addition to a Raspberry Pi Pico and PiCowbell Adalogger, you will
also need:
The following example assumes that you followed along with the RTC with
CircuitPython page in this guide to set the time on the RTC module.
CircuitPython Usage
To use with CircuitPython, you need to first install the necessary libraries into the lib
folder on your CIRCUITPY drive. Then you need to update code.py with the example
script.
Thankfully, we can do this in one go. In the example below, click the Download
Project Bundle button below to download the necessary libraries and the code.py file
in a zip file. Extract the contents of the zip file, and copy the entire lib folder and the c
ode.py file to your CIRCUITPY drive.
Your CIRCUITPY/lib folder should contain the following folders and files:
• /adafruit_bus_device
• /adafruit_register
• adafruit_mcp9808.mpy
• adafruit_pcf8523.mpy
if set_clock:
# year, mon, date, hour, min, sec, wday, yday, isdst
t = time.struct_time((2023, 3, 6, 00, 00, 00, 0, -1, -1))
time.sleep(1)
def get_temp(sensor):
temperature_celsius = sensor
temperature_fahrenheit = temperature_celsius * 9 / 5 + 32
return temperature_fahrenheit
while True:
try:
# variable for RTC datetime
t = rtc.datetime
# append SD card text file
with open("/sd/temp.txt", "a") as f:
# read temp data from mcp9808
temp = get_temp(mcp9808.temperature)
# write temp data followed by the time, comma-delimited
f.write('{},{}:{}:{}\n'.format(temp, t.tm_hour, t.tm_min, t.tm_sec))
print("data written to sd card")
# repeat every 30 seconds
time.sleep(30)
except ValueError:
print("data error - cannot write to SD card")
time.sleep(10)
Once everything is saved to the CIRCUITPY drive, connect to the serial console () to
see status information from the code.
In the example, the microSD card is mounted and the file temp.txt is created to log
temperature data from the MCP9808. Then in the loop, a temperature reading is
taken and saved to temp.txt, along with the timestamp from the RTC module, every 30
seconds. Every time data is written to the file, data written to the sd card is
written to the REPL to let you know that the code is running properly.
The RTC is an I2C device, which means it uses 2 wires to to communicate. These two
wires are used to set the time and retrieve it.
For the RTC library, we'll be using a fork of JeeLab's excellent RTC library, which is
available on GitHub (). You can do that by visiting the github repo and manually
downloading or, easier go to the Arduino Library Manager
Type in RTClib - and find the one that is by Adafruit and click Install
The first thing we'll demonstrate is a test sketch that will read the time from the RTC
once a second. We'll also show what happens if you remove the battery and replace it
since that causes the RTC to halt. So to start, remove the battery from the holder
while the PiCowbell is not powered or plugged into USB. Wait 3 seconds and then
replace the battery. This resets the RTC chip. Now load up the matching sketch for
your RTC
Open up Examples->RTClib->pcf8523
Whenever the RTC chip loses all power (including the backup battery) it will reset to
an earlier date and report the time as 0:0:0 or similar. Whenever you set the time, this
will kickstart the clock ticking.
So, basically, the upshot here is that you should never ever remove the battery once
you've set the time. You shouldn't have to and the battery holder is very snug so
unless the board is crushed, the battery won't 'fall out'
With the same sketch loaded, uncomment the line that starts with RTC.adjust like so:
if (! rtc.initialized()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
This line is very cute, what it does is take the Date and Time according the computer
you're using (right when you compile the code) and uses that to program the RTC. If
your computer time is not set right you should fix that first. Then you must press the U
pload button to compile and then immediately upload. If you compile and then upload
later, the clock will be off by that amount of time.
Then open up the Serial monitor window to show that the time has been set
Now that the RTC is merrily ticking away, we'll want to query it for the time. Let's look
at the sketch again to see how this is done
void loop () {
DateTime now = rtc.now();
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(" (");
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(") ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
There are some RTC libraries that instead have you call something like RTC.year() and
RTC.hour() to get the current year and hour. However, there's one problem where if
you happen to ask for the minute right at 3:14:59 just before the next minute rolls
over, and then the second right after the minute rolls over (so at 3:15:00) you'll see the
time as 3:14:00 which is a minute off. If you did it the other way around you could get
3:15:59 - so one minute off in the other direction.
We can also get a 'timestamp' out of the DateTime object by calling unixtime which
counts the number of seconds (not counting leapseconds) since midnight, January 1st
1970
Since there are 60*60*24 = 86400 seconds in a day, we can easily count days since
then as well. This might be useful when you want to keep track of how much time has
passed since the last query, making some math a lot easier (like checking if it's been
5 minutes later, just see if unixtime() has increased by 300, you don't have to worry
about hour changes)
Arduino Datalogging
The following example code will show you how use the PiCowbell Adalogger with
Arduino to log data from a sensor to a file on an SD card with timestamps from the
The following example assumes that you followed along with the RTC with
Arduino page to set the time with the RTC module and install the RTClib library.
Wiring
Library Installation
You can install the Adafruit MCP9808 library for Arduino using the Library Manager in
the Arduino IDE.
If the "Dependencies" window does not come up, then you already have the
dependencies installed.
If the dependencies are already installed, you must make sure you update them
through the Arduino Library Manager before loading the example!
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "Adafruit_MCP9808.h"
#include "RTClib.h"
RTC_PCF8523 rtc;
File logfile;
void setup() {
Serial.begin(115200);
while (!Serial);
Serial.println("\r\nPiCowbell Adalogger Test");
pinMode(LED_BUILTIN, OUTPUT);
if (!tempsensor.begin(0x18)) {
Serial.println("Couldn't find MCP9808! Check your connections and verify the
address is correct.");
while (1);
}
Serial.println("Found MCP9808!");
tempsensor.setResolution(3);
if (! rtc.begin()) {
if (! rtc.initialized() || rtc.lostPower()) {
Serial.println("RTC is NOT initialized, let's set the time!");
// When time needs to be set on a new device, or after a power loss, the
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
//
// Note: allow 2 seconds after inserting battery or applying external power
// without battery before calling adjust(). This gives the PCF8523's
// crystal oscillator time to stabilize. If you call adjust() very quickly
// after the RTC is powered, lostPower() may still return true.
}
// When the RTC was stopped and stays connected to the battery, it has
// to be restarted by clearing the STOP bit. Let's do this to ensure
// the RTC is running.
rtc.start();
float drift = 43; // seconds plus or minus over oservation period - set to 0 to
cancel previous calibration.
float period_sec = (7 * 86400); // total obsevation period in seconds (86400 =
seconds in 1 day: 7 days = (7 * 86400) seconds )
float deviation_ppm = (drift / period_sec * 1000000); // deviation in parts per
million (μs)
float drift_unit = 4.34; // use with offset mode PCF8523_TwoHours
// float drift_unit = 4.069; //For corrections every min the drift_unit is 4.069
ppm (use with offset mode PCF8523_OneMinute)
int offset = round(deviation_ppm / drift_unit);
// rtc.calibrate(PCF8523_TwoHours, offset); // Un-comment to perform calibration
once drift (seconds) and observation period (seconds) are correct
// rtc.calibrate(PCF8523_TwoHours, 0); // Un-comment to cancel previous
calibration
void loop() {
tempsensor.wake();
DateTime now = rtc.now();
float c = tempsensor.readTempC();
float f = tempsensor.readTempF();
Serial.println("Writing to SD card");
digitalWrite(LED_BUILTIN, HIGH);
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt", FILE_WRITE);
delay(5000);
}
Upload the sketch to your board and open up the Serial Monitor (Tools -> Serial
Monitor) at 115200 baud. You'll see the setup run with confirmation messages that the
MCP9808 has been found over I2C and the microSD card has been initialized
properly. As data is written to the microSD card, you'll see the message " Writing to
SD card " appear in the Serial Monitor, along with the temperature reading and
timestamp from the RTC. The onboard LED on the Raspberry Pi Pico will also light-up
when a write is in progress.
Downloads
Files
• PCF8523 Datasheet ()
• EagleCAD PCB files on GitHub ()
• Fritzing object in the Adafruit Fritzing Library ()