Raspberry Pi 3 Model A+ - Review

Table of contents

RoadTest: Raspberry Pi 3 Model A+

Author: aswinvenu

Creation date:

Evaluation Type: Development Boards & Tools

Did you receive all parts the manufacturer stated would be included in the package?: True

What other parts do you consider comparable to this product?: RaspberryPi 3B+, Orange Pi, Beaglebone Black and other currently available single board computers

What were the biggest problems encountered?:

Detailed Review:


Hardware:

 

Raspberry Pi 3 A+ is a scaled down version of the popular Raspberry Pi 3B+. It has got the same Broadcom BCM2837B0 - 1400MHz 64bit ARM A53 SoC with 512 MB LPDDR2 SDRAM

(compared to 1GB RAM in the 3B+ Version).

 

Board also features:

  • 1x USB 2.0
  • 1x HDMI Port
  • 4 Pole stereo output and composite video output
  • MIPI DSI Display port
  • MIPI CSI Camera port
  • 40 Pin GPIO Header
  • 2.4 GHz and 5 GHz IEE 802.11.b/g/n/ac wireless LAN, Bluetooth 4.2/BLE
  • Videocore GPU
  • H.264, MPEG-4 decode (1080p30)
  • H.264 encode (1080p30)
  • OpenGL ES 1.1, 2.0 graphics
  • 1x microusb port
  • uSD memory card slot

image

  Compare to RPi 3B+, RPi3A+ lacks:

  • extra 3 USB 2.0 Ports
  • Gigabit Ethernet over USB 2.0
  • PoE (Power over Ethernet)
  • additional 512MB of RAM.

 

Removing all these features has made the Model A+ smaller and compact than the B+ version.

Here is the comparison between RPi 3A+ and RPi 3B+ dimensions.

 

image

 

 

Model A+ has an outer dimension of 65mmx56mm and the Model B+ has 85mmx56mm. So Model A+ is approx. 1120mm2 smaller than the Model B+.

 

More Information on the product details are available from RaspberryPi website.

Helpful links are:

https://www.raspberrypi.org/app/uploads/2018/11/Raspberry_Pi_3A_product_brief.pdf

 

Talking about the build quality, PCB is well made and components are well assembled. Looks like They have used 6 Layer 1.6mm PCB.

Setting-up the working environment:

 

 

image

 

Requirements:

 

  • Raspberrypi 3 Model A+
  • 5V-2A micro-usb power supply
  • 16GB Class 10 uSD card
  • HDMI Monitor
  • Keyboard

 

STEP 1 - Download the Raspbian Image.

                Download the latest Raspbian image file from the website. https://www.raspberrypi.org/downloads/raspbian/

image

 

STEP 2 - Preparing the uSD card:

    I used Ubuntu 18.04 PC to setup my uSD card. So the following steps will be only applicable to a Linux setup only

  • Insert the uSD card to the PC using a card reader.
  • Check the block memory list to get the mount point information
  • Now unmount all the partitions belong to the uSD card.
  • unzip the image file
  • Load the .img file using dd command

 

Loading the image file will take couple of minutes.

 

image

 

Unplug and plug-in the memory card reader. Now two filesystems will be mounted to the host system. Switch the current directory to the /boot and open the config.txt file. Now add enable_uart=1 to the end of the file.

This will help us accessing the system through serial port. (Since Model A+ doesn't have Ethernet and Additional USBs, Serial console is one of the best way to configure and monitor the system )

 

image

STEP 3: Booting the Raspberry Pi:

 

  •     After the step one and two, plug in the uSD card into the RPi's uSD card slot.
  •     Connect the HDMI Cable
  •     Connect the microUSB power cable

 

I have created two bootable uSD cards of Raspbian light and Raspbian Desktop images.

Here is the boot time for both images

 

Raspbian Light

 

ModelAttempt 1Attempt 2Attempt3
RPi 3 Model A+41seconds41seconds40seconds
RPi 3 Model B+41seconds44seconds42seconds

 

Raspbian Desktop

 

ModelAttempt 1Attempt 2
Attempt 3
RPi 3 Model A+20seconds20seconds19seconds
RPi 3 Model B+19seconds19seconds19seconds

 

 

I was expecting Raspbian Light version to be booting faster than Raspbian Desktop. But from the experiment it turns out to be the opposite. (May be because of the boot log prints in the light version!)

Both RPi Model A+ and B+ booted at the same time. This is actually expected.

Power Consumption:

 

Now let us talk about the power consumption.

I made this setup to measure the current flowing through the micro-USB. This will be the overall current draw of the device.

 

Note: This is not the ideal way to measure the current, Here sampling interval of the measurement will be too high so that I can't read any quick variations in the current. The maximum possible sampling interval in this method is ~0.3 seconds.

The perfect setup will have a high precision resistor in series with the +/- line and voltage across this resistor will be recorded through a DSO(Digital Storage Oscilloscope). Since I don't have a DSO, I am proceeding with the setup I have.

 

image

My setup: An ammeter (Multimeter) connected in series with the power supply. Lets see the result I got.

 

  • Power on without any valid uSD card with image : 114mA
  • Properly booted RPi with no HDMI cable connected, ( WIFI and BLUETOOTH ON ) :    200mA
  • Properly booted RPi with HDMI cable connected (WIFI and BLUETOOTH ON)        :    218mA
  • Properly booted RPi with HDMI and USB Keyboard connected (WIFI and BLUETOOTH ON)  : 225mA
  • Above configuration with WIFI Turned Off : 187mA
  • Running Chromium Browser : 280-300mA when the task is created and settles down @ 240mA
  • Chromium browser and streaming YouTube : 360-410mA

 

      There is not much difference I can find when bluetooth is turned off vs turned on.

 

Here is the power consumption values I got from my setup while booting and shutting down. The readings are in terms of current in mAs. To get power multiply this number by 5 (P = I*A)

 

imageimage

 

Performance :

 

Here comes the performance part of the CPU. This is the CPU specs for BCM2837B0 recorded by lscpu command.

image

4 CPU cores 64 bit Cortex-A53 ARM V7 architecture. Normally CPU operates at 600MHz (This is to save power). But it can throttle upto 1400MHz when performance is required.

 

I wrote a small script to log CPU frequency, temperature and voltage.

 

# Measure Clock speed
while((1)); do  
for src in arm core; do \
        echo -e "$src:\t$(vcgencmd measure_clock $src)" ; \
done
# Measure volts
for id in core sdram_c sdram_i sdram_p ; do \
        echo -e "$id:\t$(vcgencmd measure_volts $id)" ; \
done
# Measure temperature
vcgencmd measure_temp
# Get memory split
vcgencmd get_mem arm && vcgencmd get_mem gpu 
vmstat
# Sleep 
sleep 3s
done

 

This will help me log the values into a file and analyze it later.

 

Prime number calculation is one of the best way to test the cpu. Prime number factorization will put CPU under constant load. I wrote a simple small C code for calculating the prime numbers in a given range.

 

#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>

int main(int argc, char **argv)
{
    int start, end;
    bool flag;
    start = atoi(argv[1]);
    end = atoi(argv[2]);

    for(int i = start; i < end; i++){
        flag = false;
        for(int j = 2; j <= i/2; j++){
            if((i % j) == 0){
                flag = true;
                break;
            }
        }

    }
    return 0;
}

 

Initially I ran the code to generate prime numbers from 0 to 100000 here is the result.

 

image

 

It took 9seconds and 887 milli-seconds to complete the result.

 

CPU core voltage increased from 1.2Volts to 1.3563Volts and frequency increased from 600MHz to 1400MHz in these 9seconds. It went to default values after.

Note:The same prime.c code produced the result in 613msec on my intel i5 PC.

 

This test can only throttle one CPU Core to its peak. Its evident from the below pic. Overall CPU usage is only 25 percent. Which is one fourth of the total.

image

 

So I decided to run the same test on 3 different terminals with slightly higher limits (0 - 4000000). This will push RPi's 3 cores to its maximum throughput and I can measure the temperature, voltage and frequency of the core using

the script I wrote.

image

This is before running the test.

image

This is while the test is running.

 

I Ran this test for 17minutes and capture the change in the CPU temperature, Voltage and Frequency. Here is the plot I generated from the log files I captured.

image

X axis is in 3 seconds per unit scale.

 

As you can see the temperature rise from 45 to ~60C was so fast. Once the temperature reached 60C , CPU clock dropped from 1.4GHz to 1.2GHz as well as the voltage dropped from

1.35V to 1.25V.

 

I was very curious to see the effect of a heatsink  + CPU on these parameters. Small Aluminium heatsinks are available in the market so I bought one and repeated the same test with it.

image

This time I ran the test for slightly more than 3 hours. Here is the result.

image

I am quiet impressed with the temperature stability and performance it produced.

 

On top of these I ran sysbench tests here are the results.

 

sysbench --test=cpu run

#For fileio

sysbench --test=fileio --file-total-size=2G prepare
sysbench --test=fileio --file-total-size=2G --file-test-mode=rndrw --init-rng=on --max-time=300 --max-requests=0 run
sysbench --test=fileio --file-total-size=2G cleanup

#for memory read/write
sysbench --test=memory run --memory-total-size=2G
sysbench --test=memory run --memory-total-size=2G --memory-oper=read

 

sysbench tests:

Sysbench is one of the standard programs to perform stress test.  Sysbench is not install by default. So I installed it using

 

sudo apt-get install sysbench

Sysbench has support for the following test:

 

  • CPU
  • FILE I/O
  • MEMORY READ and WRITE

 

Here is the results i got for all these tests.

sysbench test for CPU:

 

image

sysbench test for memory write :

image

sysbench test for memory read:

image

 

sysbench test for fileio:

image

image

GPIOs and Interfacing with sensors:

 

Raspberry Pi 3A+ has got 20x2 GPIO pins. We can use these to interface with different sensors and modules.

Each pin has got different multiplexed functionalities. They are

  • 1x I2C line
  • 2x SPI
  • 1xUART
  • GPIOs - General Purpose Input/Outputs

image

To use these functionalities, We need to enable these using raspi-config command.

Run the command raspi-config and select interfacing options and enable i2c and spi option as shown in the image below.

image

Testing UART :

 

To test the UART I am enabling the tty over uart option. This will let me login to the raspbian through a serial port (tty Serial). This will be an interesting use case because, Logging into raspberry pi over uart becomes the cheapest option of accessing the

board's full functionality (except the GUI part). We can even make a custom OS  (Operating System) Where ttySerial is the only way to log in to the system. For most of the embedded applications we can save a lot of power using this method.

 

For interfacing I am using pl2303 based TTL to USB converter(because my PC doesn't have a serial port). Pin Number 8 and 10 (GPIO15 and 16) are TxD and RxD respectively. Connections are as as follows.

 

 

PinFunction
8, BCM14TxD
10, BCM15RxD
9, GNDGND

 

 

 

image

 

On my Host PC I used screen to open the ttyUSB detected. The default baudrate is 115200.

 

screen /dev/ttyUSB0 115200

 

Got a login page to raspbian and everything worked smoothly as expected.

image

 

Testing I2C :

 

To test the I2C communication functionality I used MAX30100 based HeartRate Click board from MikroElektronika. Pin numbers 3 and 5 can be used as SDA and SCL respectively. 3V3 power is given from pin number one.

Datasheet of the IC is available here : https://datasheets.maximintegrated.com/en/ds/MAX30100.pdf

image

 

There are multiple ways of using I2C bus on raspberrypi.

 

image

# Detect the i2c devices in i2c bus 1 
i2cdetect -y 1

# Read the Rev. ID of the sensor
i2cget -y 1 0x57 0xFE


# Read the Part. ID of the sensor
i2cget -y 1 0x57 0xFF

# Enable temperature and SpO2 mode
 i2cset -y 1 0x57 0x06 0x0B

# Enable the high resolution SpO2 mode
i2cset -y 1 0x57 0x07 0x40

# Change the LED Current setting to a higher value
i2cset -y 1 0x57 0x07 0x40

# Read the interrupt status
i2cget -y 1 0x57 0x00

# Read the read and write pointer
i2cget -y 1 0x57 0x04
i2cget -y 1 0x57 0x02

# Get the difference and start reading the data
i2cget -y 1 0x57 0x04

# Get the temperature reading
# Integer part
i2cget -y 1 0x57 0x16
# Decimal part
i2cget -y 1 0x57 0x17

 

imageimage

 

The same can be achieved using a simple python code:

import smbus
import time

I2C_ADDR = 0x57   

# Create an object in smbus class (I2C1)
i2c = smbus.SMBus(1)

# Read the RevID and Part ID
RevID = i2c.read_byte_data(I2C_ADDR, 0xFE)
print "RevID =",hex(RevID)
PartID = i2c.read_byte_data(I2C_ADDR, 0xFF)
print "PartID = ",hex(PartID)

# Set the config Params
i2c.write_byte_data(I2C_ADDR, 0x06, 0x0B)
i2c.write_byte_data(I2C_ADDR, 0x07, 0x40)
i2c.write_byte_data(I2C_ADDR, 0x09, 0x33)

# Read the temperature
temp_int = i2c.read_byte_data(I2C_ADDR, 0x16)
temp_frac = i2c.read_byte_data(I2C_ADDR, 0x17)
print "Temp ="+str(temp_int)+"."+str(temp_frac)

# Get the available samples
read_ptr = i2c.read_byte_data(I2C_ADDR, 0x02)
write_ptr = i2c.read_byte_data(I2C_ADDR, 0x04)

time.sleep(1)

no_of_samples = (write_ptr - read_ptr)

# read all the samples
IR_MSB = i2c.read_byte_data(I2C_ADDR, 0x05)
IR_LSB = i2c.read_byte_data(I2C_ADDR, 0x05)
print "IR Sample =", ((IR_MSB << 8)|(IR_LSB))&0xffff
RED_MSB = i2c.read_byte_data(I2C_ADDR, 0x05)
RED_LSB = i2c.read_byte_data(I2C_ADDR, 0x05)
print "RED Sample =", ((RED_MSB << 8)|(RED_LSB))&0xffff

image

 

Testing SPI (Serial Peripheral ):

 

RaspberryPi 3A+ has got 2 SPI buses available to the users.

 

There are multiple ways of using I2C bus on raspberrypi.

 

  • WiringPi library in C
  • spdev library in python
  • accessing the /dev/spidev0.0 , /dev/spidev0.1
  • ioct and linux spdev using C

 

WiringPi python library https://github.com/WiringPi/WiringPi-Python

 

As a part of the initial testing I shorted MOSI(Master Out Slave In) and MISO (Master In Slave Out). This will let me clock out data to and fro RPi3A+.

 

I found a piece of code written by Anton Vorontsov to perform the same.

 

The wiring will look like this:

image

 

 

/*
 * SPI testing utility (using spidev driver)
 *
 * Copyright (c) 2007 MontaVista Software, Inc.
 * Copyright (c) 2007 Anton Vorontsov <avorontsov@ru.mvista.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License.
 *
 * Cross-compile with cross-gcc -I/path/to/cross-kernel/include
 */

#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>

#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))

static void pabort(const char *s)
{
perror(s);
abort();
}

static const char *device = "/dev/spidev1.1";
static uint8_t mode;
static uint8_t bits = 8;
static uint32_t speed = 500000;
static uint16_t delay;

static void transfer(int fd)
{
int ret;
uint8_t tx[] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x40, 0x00, 0x00, 0x00, 0x00, 0x95,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD,
0xF0, 0x0D,
};
uint8_t rx[ARRAY_SIZE(tx)] = {0, };
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long)tx,
.rx_buf = (unsigned long)rx,
.len = ARRAY_SIZE(tx),
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
};

ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1)
pabort("can't send spi message");

for (ret = 0; ret < ARRAY_SIZE(tx); ret++) {
if (!(ret % 6))
puts("");
printf("%.2X ", rx[ret]);
}
puts("");
}

static void print_usage(const char *prog)
{
printf("Usage: %s [-DsbdlHOLC3]\n", prog);
puts(" -D --device device to use (default /dev/spidev1.1)\n"
" -s --speed max speed (Hz)\n"
" -d --delay delay (usec)\n"
" -b --bpw bits per word \n"
" -l --loop loopback\n"
" -H --cpha clock phase\n"
" -O --cpol clock polarity\n"
" -L --lsb least significant bit first\n"
" -C --cs-high chip select active high\n"
" -3 --3wire SI/SO signals shared\n");
exit(1);
}

static void parse_opts(int argc, char *argv[])
{
while (1) {
static const struct option lopts[] = {
{ "device", 1, 0, 'D' },
{ "speed", 1, 0, 's' },
{ "delay", 1, 0, 'd' },
{ "bpw", 1, 0, 'b' },
{ "loop", 0, 0, 'l' },
{ "cpha", 0, 0, 'H' },
{ "cpol", 0, 0, 'O' },
{ "lsb", 0, 0, 'L' },
{ "cs-high", 0, 0, 'C' },
{ "3wire", 0, 0, '3' },
{ "no-cs", 0, 0, 'N' },
{ "ready", 0, 0, 'R' },
{ NULL, 0, 0, 0 },
};
int c;

c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL);

if (c == -1)
break;

switch (c) {
case 'D':
device = optarg;
break;
case 's':
speed = atoi(optarg);
break;
case 'd':
delay = atoi(optarg);
break;
case 'b':
bits = atoi(optarg);
break;
case 'l':
mode |= SPI_LOOP;
break;
case 'H':
mode |= SPI_CPHA;
break;
case 'O':
mode |= SPI_CPOL;
break;
case 'L':
mode |= SPI_LSB_FIRST;
break;
case 'C':
mode |= SPI_CS_HIGH;
break;
case '3':
mode |= SPI_3WIRE;
break;
case 'N':
mode |= SPI_NO_CS;
break;
case 'R':
mode |= SPI_READY;
break;
default:
print_usage(argv[0]);
break;
}
}
}

int main(int argc, char *argv[])
{
int ret = 0;
int fd;

parse_opts(argc, argv);

fd = open(device, O_RDWR);
if (fd < 0)
pabort("can't open device");

/*
* spi mode







*/
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
if (ret == -1)
pabort("can't set spi mode");

ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
if (ret == -1)
pabort("can't get spi mode");

/*
* bits per word
*/
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't set bits per word");

ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't get bits per word");

/*
* max speed hz
*/
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't set max speed hz");

ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't get max speed hz");

printf("spi mode: %d\n", mode);
printf("bits per word: %d\n", bits);
printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);

transfer(fd);

close(fd);

return ret;
}

 

 

Here is the result I got.

image

 

To test the SPI bus functionalities on a real project I used Nokia5110 LCD module.

image

 

Connections are made as per the table

 

FunctionPin Number
MOSI19, BCM10
SCK23, BCM11
CS126, BCM7
RST18, BCM24
DC16, BCM23
GND9, GND
VCC

1, 3v3

BL17, 3v3

image

 

I wrote a small code in python to show the bitmap image of element14 logo.

 

import spidev
import RPi.GPIO as GPIO
import time

# Element14 logo 84x48
logo = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0xe0, 0xf0, 0x30, 0x10, 0x10, 0x70, 0xe0, 0x80, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xe0, 0xf0, 0x30, 0x10, 0x10, 0x70, 0xe0, 0x80, 0x00, 0xf0, 0xf0, 0x30, 0x10, 0x10, 0xf0, 0xe0, 0x70, 0x10, 0x10, 0x30, 0xf0, 0xc0, 0x00, 0x00, 0xe0, 0xf0, 0x30, 0x10, 0x10, 0x70, 0xe0, 0x80, 0x00, 0xf0, 0xf0, 0x30, 0x10, 0x10, 0x70, 0xf0, 0x80, 0x00, 0x10, 0xfc, 0xfc, 0x10, 0x10, 0x10, 0x00, 0x04, 0x04, 0x06, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xe0, 0x38, 0x1c, 0x7e, 0xfe, 0x48, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x07, 0x0f, 0x0d, 0x09, 0x09, 0x0d, 0x0d, 0x01, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x07, 0x0f, 0x0d, 0x09, 0x09, 0x09, 0x0d, 0x01, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x0d, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x07, 0x0f, 0x0d, 0x09, 0x09, 0x0d, 0x0d, 0x01, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0a, 0x00, 0x00, 0x07, 0x0f, 0x08, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x0f, 0x0f, 0x08, 0x08, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0f, 0x0f, 0x05, 0x01, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]


# Assign Data/Command pin and Reset Pin
dc_pin = 23
rst_pin = 24

# Set the GPIO Numbering to BCM numbering
GPIO.setmode(GPIO.BCM)

# Set the mode of GPIO operations as OUTPUT
GPIO.setup(dc_pin, GPIO.OUT)
GPIO.setup(rst_pin, GPIO.OUT)

# Reset the LCD by toggling the RESET Pin
GPIO.output(rst_pin, GPIO.LOW)
time.sleep(0.1)
GPIO.output(rst_pin, GPIO.HIGH)

# Start a new SPI instance on SPI0 using CS1
spi = spidev.SpiDev()
spi.open(0, 1)
spi.max_speed_hz = 100000

# Commands
GPIO.output(dc_pin, GPIO.LOW)

# Change mode to extended commands 
spi.xfer2([0x21])
# Set Vop
spi.xfer2([0xB0])
# Set Temp Coeff
spi.xfer2([0x04])
# Set LCD Bias mode
spi.xfer2([0x14])

# Change mode to normal commands mode
spi.xfer2([0x20])
spi.xfer2([0x0c])

# Change the contrast
spi.xfer2([0x21])
spi.xfer2([0x80 | 50])
spi.xfer2([0x20])

# Send the data
GPIO.output(dc_pin, GPIO.HIGH)
for i in range(0,503):
    spi.xfer2([logo[i]])

 

 

Running a neural network inference engine (yolo):

 

Neural network is a hot topic these days and the technology is trending. So I decided test the Neural network inference engine on raspberrypi3A+

Inference engines uses a trained network to predict/classify a new data.

 

Yolo3 is a very famous implementaion of neural network. It has got really high accuracy and performance.Read more here:https://pjreddie.com/darknet/yolo/

 

I downloaded AlexeyAB's version of darknet since the original darknet doesn't run raspberrypis.

 

git clone https://github.com/AlexeyAB/darknet.git

 

cd darknet/
make

 

this make doesn't require any additional libraries. Once the make is complete we will get darknet executable

 

wget https://pjreddie.com/media/files/yolov3-tiny.weights

 

Yolo has a original full weights for the network and a lite version. Without proper GPU acceleration, running full version of the network will be a heavylifting and I wont be able to make any practical output from that. So I downloaded the lite version.

 

./darknet detect cfg/yolov3-tiny.cfg yolov3-tiny.weights data/dog.jpg

 

image

Here is the result I got.

 


image

OceanFFT graphics test:

 

As a final test I ran OceanFFT test to test the GPU performance. Code can be downloaded from here:

https://github.com/deiss/fftocean/blob/master/README.md

 

To build the code we have to download freeglut (OpenGL Utility Toolkit)

 

sudo apt-get install freeglut3 freeglut3-dev

 

build the code and ran the fftocean executable.

 

I got a steady 4 fps output for most of the time.

 

image

Conclusions:

 

After doing all these tests and playing with the board for almost a month. I am pretty much happy with performance the board given. This board will be a good option for any embedded projects which requires better CPU performance than a Cortex M controllers with a moderate power budget.

 

It would have been great if raspberrypi in general can feature ADC (Analog to digital converter) in the GPIO header.

Anonymous