Arm Community
Arm Community
  • Site
  • User
  • Site
  • Search
  • User
Arm Community blogs
Arm Community blogs
Embedded and Microcontrollers blog "8th" - Embedded and more (part 2)
  • Blogs
  • Mentions
  • Sub-Groups
  • Tags
  • Jump...
  • Cancel
More blogs in Arm Community blogs
  • AI blog

  • Announcements

  • Architectures and Processors blog

  • Automotive blog

  • Embedded and Microcontrollers blog

  • Internet of Things (IoT) blog

  • Laptops and Desktops blog

  • Mobile, Graphics, and Gaming blog

  • Operating Systems blog

  • Servers and Cloud Computing blog

  • SoC Design and Simulation blog

  • Tools, Software and IDEs blog

Tags
  • Raspberry Pi
  • Embedded Linux
  • Embedded
  • Raspberry Pi 2
  • Programming Languages
  • Tutorial
Actions
  • RSS
  • More
  • Cancel
Related blog posts
Related forum threads

"8th" - Embedded and more (part 2)

Ron Aaron
Ron Aaron
December 13, 2017

Overview

This is the second in a series of articles in which we explore using the 8th programming language with embedded as well as desktop and server systems, in an integrated project. The first in the series is "8th": Embedded and more (part 1).

It is not intended to be a tutorial on how to use 8th: for that, you can see the 8th tutorials, the 8th manual, the 8th forum, or you can start here: 8th - a Gentle Introduction to a Modern Forth.

Raspberry Pi board

Next steps

In the previous article in this series we created a very simple framework application which admittedly did nothing but give you a feel for how the data-collection code might work. This time we'll flesh that part out, but to do that we also need to assemble the hardware. So without further ado, let's begin!

The hardware

We need to connect the LM75A Temperature Sensor (henceforth "board") to the Raspberry Pi 2 (or 3) using the I2C connection on the RPI. First we need to assemble the sensor, since it comes with a header separate from the board. Simply solder the header to the board. Then, jumper the pins as follows:

Board RPI pin
VCC 1
GND 6
SDA 3
SCL 5

The "OS" pin on the board need not be connected to anything. Likewise, for the moment we won't jumper anything on the back of the board (doing so changes the I2C address of the board).

Testing the setup

You need to have installed at least the Hobbyist version of 8th on your RPI in order to run this code, since it has support for I2C. For a limited time you can purchase the current Professional version and automatically receive the Embedded version as soon as it's released. More details here.

You'll also need to enable I2C on your RPI. Start raspi-config, option 5, then P5. Or you can manually enable the kernel modules "i2c-bcm2708" and "i2c-dev". If you've installed "i2c-tools" on your RPI, you can test the board's connection by typing i2cdetect -y 1, which should show a "48" amongst a field of dashes. That "48" is the hex address of the board, as currently configured.

So to test this with 8th, start 8th, and type in the console:

1 0x48 hw:i2c
0 false hw:i2c@reg
.s bye

You should see something like:

2 n: 017d2620 1 32786
1 hw: 017ee000 1 unknown

That means that the word (2-byte) value 32786 was read from the I2C device at address 0x48, register 0, and was put on TOS (top of stack). The 'hw' item below that is 8th's I2C handle for the board. If you see 'null' instead of a number, then the number you gave for the address is incorrect, or possibly your board is defective or not wired up correctly, or it's unhappy because you're touching it. Double-check all of that!

NOTE: the board is very sensitive to being touched. A slight amount of skin oil on the back surface can change the address it uses. Touching the sensor can freak it out so it returns 'null'. Be careful!

The software

The full code is here so you don't have to type it all in. Usual practice is to put the code in a file (in this case, 'data.8th') and then load it using 8th data.8th.

We'll just discuss some of the highlights of the code. Notice, first of all, that the code's main loop is mostly the same as the previous (non-functional) version:

: app:main
\ time-stamp log output:
true log-time

"Starting" log
init-devices

repeat
collect-data null? if
\ Couldn't read; ignore
drop
else
save-data
send-data
then
1 sleep
again ;

The differences are that we tell 8th we want the 'log' word to output a time-stamp, we added a "init-devices" word, and we check to see if the "collect-data" word returned valid data. And it's the "collect-data" word that's more interesting:

\ Read the device:
: collect-data \ -- tempC
LM75A @
\ Read a 2-byte word from the device:
0 false hw:i2c@reg nip
null? not if
\ Convert the data to a real value:
cvt-raw
then ;

As the comments state, this reads a word from the device and then converts it from the raw data format into a temperature in degrees Celsius. The data-sheet for the LM75A is useful for figuring out how to do this. The "cvt-raw" word does the hard work:

\ Take raw data from device and convert to actual number:
: cvt-raw \ n1 -- n2
\ reverse the bytes and shift off the insignificant:
bswap 5 n:shr

\ if top bit set, it's negative:
dup %10000000000 band if 2comp n:neg then

\ value is eighths of a degree C
8 n:/ ;

The "bswap" and "2comp" words aren't part of 8th, but they're in the full source file.

The output

When you run the sample code on a properly configured RPI and board, you'll get something like this:

Readings

Note the full time-stamp which we enabled with "true log-time". Also note we print the Fahrenheit as well as Celsius values. The temperature rose during this run because I put my thumb on the sensor, and some data points are missing precisely because my thumb's presence caused the sensor to not return a value.

Next up

In the next blog post, we'll take a look at hooking up the 7-segment display and interfacing it with 8th. The inspiration for this series is taken from this post though some of what's written there proved to be incorrect.

Anonymous
Embedded and Microcontrollers blog
  • Formally verifying a floating-point division routine with Gappa – part 2

    Simon Tatham
    Simon Tatham
    A method of testing whether a numerical error analysis using Gappa really matches the code it is intended to describe.
    • September 4, 2025
  • Formally verifying a floating-point division routine with Gappa – part 1

    Simon Tatham
    Simon Tatham
    Learn the basics of using Gappa for numerical error analysis, using floating-point division in Arm machine code as a case study.
    • September 4, 2025
  • Adapting Kubernetes for high-performance IoT Edge deployments

    Alexandre Peixoto Ferreira
    Alexandre Peixoto Ferreira
    In this blog post, we address heterogeneity in IoT edge deployments using Kubernetes.
    • August 21, 2024