{"id":3407,"date":"2026-10-29T12:21:34","date_gmt":"2026-10-29T12:21:34","guid":{"rendered":"https:\/\/www.robertprice.co.uk\/robblog\/?p=3407"},"modified":"2026-10-29T12:21:35","modified_gmt":"2026-10-29T12:21:35","slug":"rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014","status":"publish","type":"post","link":"https:\/\/www.robertprice.co.uk\/robblog\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\/","title":{"rendered":"RC2026 \u2013 Part 4 \u2013 Reading the temperature from a BME280 on an RC2014"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">In my previous posts, I&#8217;ve shown how to read the ID value from a BME280 sensor using an RC2014 computer. That&#8217;s not very useful in itself, but it is a good building block for getting practical information from the sensor. In this post, I&#8217;m going to read the current temperature.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The temperature isn&#8217;t returned as a sensible, human-understandable value directly from the sensor. It needs to be calculated using calibration data that the BME280 also supplies. The <a href=\"https:\/\/www.bosch-sensortec.com\/media\/boschsensortec\/downloads\/datasheets\/bst-bme280-ds002.pdf\">BME280 datasheet<\/a> gives us an algorithm to do this.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.robertprice.co.uk\/robblog\/assets\/Screenshot-2026-10-29-at-10.46.01.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"325\" src=\"https:\/\/www.robertprice.co.uk\/robblog\/assets\/Screenshot-2026-10-29-at-10.46.01-1024x325.png\" alt=\"\" class=\"wp-image-3409\" srcset=\"https:\/\/www.robertprice.co.uk\/robblog\/assets\/Screenshot-2026-10-29-at-10.46.01-1024x325.png 1024w, https:\/\/www.robertprice.co.uk\/robblog\/assets\/Screenshot-2026-10-29-at-10.46.01-300x95.png 300w, https:\/\/www.robertprice.co.uk\/robblog\/assets\/Screenshot-2026-10-29-at-10.46.01-1536x487.png 1536w, https:\/\/www.robertprice.co.uk\/robblog\/assets\/Screenshot-2026-10-29-at-10.46.01-767x243.png 767w, https:\/\/www.robertprice.co.uk\/robblog\/assets\/Screenshot-2026-10-29-at-10.46.01-1200x380.png 1200w, https:\/\/www.robertprice.co.uk\/robblog\/assets\/Screenshot-2026-10-29-at-10.46.01.png 1798w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">I also need to tell the BME280 to continually sense; otherwise, it is in sleep mode.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The BME280 is a very well-known sensor, and there are some libraries written for other systems that I can use to verify my work. Adafruit has a <a href=\"https:\/\/github.com\/adafruit\/Adafruit_BME280_Library\">BME280 library for the Arduino<\/a> that is written in C++. I am going to use some of the code from the Adafruit library where possible.  <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Writing and reading data<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">My previous post had a transfer routine to handle the bit-banging of SPI data, so I am going to build upon this.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The first routine we need is one to send and receive data of different lengths. I pass in address locations and lengths. The routine will then bit-bang that amount of data. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void write_then_read(const uint8_t *write_data, uint8_t write_length, uint8_t *read_data, uint8_t read_length) {\n    \/\/ Deselect the BME280 to ensure it's not selected before starting communication.\n    io_spi = SELECT | CLK | MOSI;\n\n    \/\/ Write data\n    for (uint8_t i = 0; i &lt; write_length; i++) {\n        transfer(write_data&#91;i]);\n    }\n\n    \/\/ Read data\n    for (uint8_t i = 0; i &lt; read_length; i++) {\n        read_data&#91;i] = transfer(0x00); \/\/ Send dummy byte to read\n    }\n\n    \/\/ Deselect the BME280 after communication is done.\n    io_spi = SELECT | CLK | MOSI;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">I need to be able to read in 8 bit, 16 bit, and 24 bit values in little-endian format,  both signed and unsigned, as well as to be able to write an 8 bit value. These utility routines can help with that.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void write8(uint8_t reg, uint8_t value) {\n    uint8_t write_data&#91;2] = { reg &amp; 0x7F, value }; \/\/ Clear MSB\n    write_then_read(write_data, 2, NULL, 0);\n}   \n\nuint8_t read8(uint8_t reg) {\n    uint8_t write_data&#91;1] = { reg };\n    uint8_t read_data&#91;1] = { 0 };\n\n    write_then_read(write_data, 1, read_data, 1);\n    return read_data&#91;0];\n}\n\nuint16_t read16_LE(uint8_t reg) {\n    uint8_t write_data&#91;1] = { reg };\n    uint8_t read_data&#91;2] = { 0 };\n\n    write_then_read(write_data, 1, read_data, 2);\n    return (read_data&#91;1] &lt;&lt; 8) | read_data&#91;0];\n}\n\nint16_t readS16_LE(uint8_t reg) {\n    return (int16_t)read16_LE(reg);\n}   \n\nuint32_t read24(uint8_t reg) {\n    uint8_t write_data&#91;1] = { reg };\n    uint8_t read_data&#91;3] = { 0 };\n\n    write_then_read(write_data, 1, read_data, 3);\n    uint32_t value = 0;\n    value |= read_data&#91;0];\n    value &lt;&lt;= 8;\n    value |= read_data&#91;1];\n    value &lt;&lt;= 8;\n    value |= read_data&#91;2];\n    return value;\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">BME280 registers<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The BME280 has numerous registers we can read and write to. The ID we retrieve in the previous blog post uses register 0xd0. Adafruit has defined all of these in their library, so I will reuse their code for this.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>enum {\n  BME280_REGISTER_DIG_T1 = 0x88,\n  BME280_REGISTER_DIG_T2 = 0x8A,\n  BME280_REGISTER_DIG_T3 = 0x8C,\n\n  BME280_REGISTER_DIG_P1 = 0x8E,\n  BME280_REGISTER_DIG_P2 = 0x90,\n  BME280_REGISTER_DIG_P3 = 0x92,\n  BME280_REGISTER_DIG_P4 = 0x94,\n  BME280_REGISTER_DIG_P5 = 0x96,\n  BME280_REGISTER_DIG_P6 = 0x98,\n  BME280_REGISTER_DIG_P7 = 0x9A,\n  BME280_REGISTER_DIG_P8 = 0x9C,\n  BME280_REGISTER_DIG_P9 = 0x9E,\n\n  BME280_REGISTER_DIG_H1 = 0xA1,\n  BME280_REGISTER_DIG_H2 = 0xE1,\n  BME280_REGISTER_DIG_H3 = 0xE3,\n  BME280_REGISTER_DIG_H4 = 0xE4,\n  BME280_REGISTER_DIG_H5 = 0xE5,\n  BME280_REGISTER_DIG_H6 = 0xE7,\n\n  BME280_REGISTER_CHIPID = 0xD0,\n  BME280_REGISTER_VERSION = 0xD1,\n  BME280_REGISTER_SOFTRESET = 0xE0,\n\n  BME280_REGISTER_CAL26 = 0xE1, \/\/ R calibration stored in 0xE1-0xF0\n\n  BME280_REGISTER_CONTROLHUMID = 0xF2,\n  BME280_REGISTER_STATUS = 0XF3,\n  BME280_REGISTER_CONTROL = 0xF4,\n  BME280_REGISTER_CONFIG = 0xF5,\n  BME280_REGISTER_PRESSUREDATA = 0xF7,\n  BME280_REGISTER_TEMPDATA = 0xFA,\n  BME280_REGISTER_HUMIDDATA = 0xFD\n};<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Setting the sampling rate<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The BME280 doesn&#8217;t do much unless it&#8217;s told to. So we need a routine to turn it on and get it sampling data. There are various configurations defined in the BME280 documentation, but I&#8217;m going to lift these values from the Adafruit library, as they have done the hard work of turning them into enum values already.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>enum sensor_mode {\n    MODE_SLEEP = 0b00,\n    MODE_FORCED = 0b01,\n    MODE_NORMAL = 0b11\n};\n\nenum sensor_filter {\n    FILTER_OFF = 0b000,\n    FILTER_X2 = 0b001,\n    FILTER_X4 = 0b010,\n    FILTER_X8 = 0b011,\n    FILTER_X16 = 0b100\n};\n\nenum sensor_sampling {\n    SAMPLING_NONE = 0b000,\n    SAMPLING_X1 = 0b001,\n    SAMPLING_X2 = 0b010,\n    SAMPLING_X4 = 0b011,\n    SAMPLING_X8 = 0b100,\n    SAMPLING_X16 = 0b101\n};<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To set the sampling rate, I need to perform several operations. I first put the BME280 to sleep. This allows me to safely update the configuration and control registers.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void setSampling(enum sensor_mode mode, enum sensor_filter filter, enum standby_duration duration) {\n    \/\/ Set the sensor to sleep mode before changing settings\n    write8(BME280_REGISTER_CONTROL, MODE_SLEEP); \n\n    \/\/ Set the humidity oversampling to x1 (0b001)\n    write8(BME280_REGISTER_CONTROLHUMID, 0b001);\n\n    \/\/ Set the filter and standby duration in the config register\n    uint8_t config = (duration &lt;&lt; 5) | (filter &lt;&lt; 2);\n    write8(BME280_REGISTER_CONFIG, config);\n\n    \/\/ Set the temperature and pressure oversampling to x1 (0b001)\n    \/\/ and the mode\n    uint8_t control = (0b001 &lt;&lt; 5) | (0b001 &lt;&lt; 2) | mode;\n    write8(BME280_REGISTER_CONTROL, control);\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Reading the calibration coefficients<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">I mentioned earlier the need to use calibration data to calculate the temperature. We need to get these values and store them.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>typedef struct {\n  uint16_t dig_T1; \/\/\/&lt; temperature compensation value\n  int16_t dig_T2;  \/\/\/&lt; temperature compensation value\n  int16_t dig_T3;  \/\/\/&lt; temperature compensation value\n\n  uint16_t dig_P1; \/\/\/&lt; pressure compensation value\n  int16_t dig_P2;  \/\/\/&lt; pressure compensation value\n  int16_t dig_P3;  \/\/\/&lt; pressure compensation value\n  int16_t dig_P4;  \/\/\/&lt; pressure compensation value\n  int16_t dig_P5;  \/\/\/&lt; pressure compensation value\n  int16_t dig_P6;  \/\/\/&lt; pressure compensation value\n  int16_t dig_P7;  \/\/\/&lt; pressure compensation value\n  int16_t dig_P8;  \/\/\/&lt; pressure compensation value\n  int16_t dig_P9;  \/\/\/&lt; pressure compensation value\n\n  uint8_t dig_H1; \/\/\/&lt; humidity compensation value\n  int16_t dig_H2; \/\/\/&lt; humidity compensation value\n  uint8_t dig_H3; \/\/\/&lt; humidity compensation value\n  int16_t dig_H4; \/\/\/&lt; humidity compensation value\n  int16_t dig_H5; \/\/\/&lt; humidity compensation value\n  int8_t dig_H6;  \/\/\/&lt; humidity compensation value\n} bme280_calib_data;\n\nbme280_calib_data _bme280_calib;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The calibration data is a mix of signed and unsigned integers of various lengths. I can use the various read functions I defined earlier to read and save these.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void readCoefficients(void) {\n  _bme280_calib.dig_T1 = read16_LE(BME280_REGISTER_DIG_T1);\n  _bme280_calib.dig_T2 = readS16_LE(BME280_REGISTER_DIG_T2);\n  _bme280_calib.dig_T3 = readS16_LE(BME280_REGISTER_DIG_T3);\n\n  _bme280_calib.dig_P1 = read16_LE(BME280_REGISTER_DIG_P1);\n  _bme280_calib.dig_P2 = readS16_LE(BME280_REGISTER_DIG_P2);\n  _bme280_calib.dig_P3 = readS16_LE(BME280_REGISTER_DIG_P3);\n  _bme280_calib.dig_P4 = readS16_LE(BME280_REGISTER_DIG_P4);\n  _bme280_calib.dig_P5 = readS16_LE(BME280_REGISTER_DIG_P5);\n  _bme280_calib.dig_P6 = readS16_LE(BME280_REGISTER_DIG_P6);\n  _bme280_calib.dig_P7 = readS16_LE(BME280_REGISTER_DIG_P7);\n  _bme280_calib.dig_P8 = readS16_LE(BME280_REGISTER_DIG_P8);\n  _bme280_calib.dig_P9 = readS16_LE(BME280_REGISTER_DIG_P9);\n\n  _bme280_calib.dig_H1 = read8(BME280_REGISTER_DIG_H1);\n  _bme280_calib.dig_H2 = readS16_LE(BME280_REGISTER_DIG_H2);\n  _bme280_calib.dig_H3 = read8(BME280_REGISTER_DIG_H3);\n  _bme280_calib.dig_H4 = ((int8_t)read8(BME280_REGISTER_DIG_H4) &lt;&lt; 4) |\n                         (read8(BME280_REGISTER_DIG_H4 + 1) &amp; 0xF);\n  _bme280_calib.dig_H5 = ((int8_t)read8(BME280_REGISTER_DIG_H5 + 1) &lt;&lt; 4) |\n                         (read8(BME280_REGISTER_DIG_H5) >> 4);\n  _bme280_calib.dig_H6 = (int8_t)read8(BME280_REGISTER_DIG_H6);    \n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Reading the temperature<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The example code given in the BME280 datasheet returned the temperature as an integer, but for ease of use, I will want to use a floating-point value. This is simply the value from the datasheet divided by 100 to give us a value in Celsius. This routine makes extensive use of the calibration data from the BME280.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"> <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int32_t t_fine;\nint32_t t_fine_adjust = 0;\n\nfloat readTemperature(void) {\n    int32_t var1, var2;\n    int32_t adc_T = read24(BME280_REGISTER_TEMPDATA);\n    adc_T >>= 4;\n\n    var1 = (int32_t)((adc_T \/ 8) - ((int32_t)_bme280_calib.dig_T1 * 2));\n    var1 = (var1 * ((int32_t)_bme280_calib.dig_T2)) \/ 2048;\n    var2 = (int32_t)((adc_T \/ 16) - ((int32_t)_bme280_calib.dig_T1));\n    var2 = (((var2 * var2) \/ 4096) * ((int32_t)_bme280_calib.dig_T3)) \/ 16384;\n\n    t_fine = var1 + var2 + t_fine_adjust;\n\n    int32_t T = (t_fine * 5 + 128) \/ 256;\n\n    return (float)T \/ 100;\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Putting it all together<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">I have enough code to be able to read the temperature from the BME280, so it&#8217;s time to put it all together. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The first thing I need to do is reset the BME280. I can do this by writing to the soft reset register. Secondly, I turn on the BME280 and get it sampling. Next, I read the calibration data. Finally, in a loop, I can continually read the temperature and display it to my serial terminal.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int main(void) {\n    write8(BME280_REGISTER_SOFTRESET, 0xB6);\n\n    setSampling(MODE_NORMAL, FILTER_OFF, SAMPLING_X16);\n\n    readCoefficients();\n\n    while(1) {\n      float temperature = readTemperature();\n      printf(\"Temperature: %.2f\u00b0C\\n\", temperature);\n    }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Compiling the code<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Because I am using floating-point numbers, I need to include the maths library when compiling. I do this using the <code>-lm<\/code> flag.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The printf command doesn&#8217;t handle floating-point numbers by default, so I also need to enable this. This is done using a C pragma.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#pragma printf %f<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When I compile the application using z88dk zcc, my command line looks like this.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>zcc +rc2014 -subtype=basic -clib=sdcc_iy -lm -v -m -SO3 --max-allocs-per-node200000 bme280.c -o bme280 -create-app<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Running the code<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">It was very satisfying to see real temperatures on screen when I ran the code. The thermostat in my room was set to 18C, so this seems to be working really well.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.robertprice.co.uk\/robblog\/assets\/Screenshot-2026-10-24-at-16.07.25.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"373\" src=\"https:\/\/www.robertprice.co.uk\/robblog\/assets\/Screenshot-2026-10-24-at-16.07.25-1024x373.png\" alt=\"Temperature readings of 18.39C being shown in a terminal window.\" class=\"wp-image-3423\" srcset=\"https:\/\/www.robertprice.co.uk\/robblog\/assets\/Screenshot-2026-10-24-at-16.07.25-1024x373.png 1024w, https:\/\/www.robertprice.co.uk\/robblog\/assets\/Screenshot-2026-10-24-at-16.07.25-300x109.png 300w, https:\/\/www.robertprice.co.uk\/robblog\/assets\/Screenshot-2026-10-24-at-16.07.25-767x279.png 767w, https:\/\/www.robertprice.co.uk\/robblog\/assets\/Screenshot-2026-10-24-at-16.07.25-1200x437.png 1200w, https:\/\/www.robertprice.co.uk\/robblog\/assets\/Screenshot-2026-10-24-at-16.07.25.png 1248w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/a><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>In my previous posts, I&#8217;ve shown how to read the ID value from a BME280 sensor using an RC2014 computer. That&#8217;s not very useful in itself, but it is a good building block for getting practical information from the sensor. In this post, I&#8217;m going to read the current temperature. The temperature isn&#8217;t returned as &hellip; <a href=\"https:\/\/www.robertprice.co.uk\/robblog\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;RC2026 \u2013 Part 4 \u2013 Reading the temperature from a BME280 on an RC2014&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":3387,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[157,209,187],"tags":[215,117,219,213],"class_list":["post-3407","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-rc2014","category-rc2026","category-retrochallenge","tag-bme280","tag-rc2014","tag-rc2026","tag-spi"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>RC2026 \u2013 Part 4 \u2013 Reading the temperature from a BME280 on an RC2014 - Robert Price<\/title>\n<meta name=\"description\" content=\"Reading the temperature using a BME280 sensor attached to an RC2014 Z80 computer. The code is bit-banging the SPI protocol to retrieve data.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.robertprice.co.uk\/robblog\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"RC2026 \u2013 Part 4 \u2013 Reading the temperature from a BME280 on an RC2014 - Robert Price\" \/>\n<meta property=\"og:description\" content=\"Reading the temperature using a BME280 sensor attached to an RC2014 Z80 computer. The code is bit-banging the SPI protocol to retrieve data.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.robertprice.co.uk\/robblog\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\/\" \/>\n<meta property=\"og:site_name\" content=\"Robert Price\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-29T12:21:34+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-10-29T12:21:35+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.robertprice.co.uk\/robblog\/assets\/BME280-RC2014.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1600\" \/>\n\t<meta property=\"og:image:height\" content=\"1200\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"rob\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"rob\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\\\/\"},\"author\":{\"name\":\"rob\",\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/#\\\/schema\\\/person\\\/fac6d5b076e0e14e1fb13e15b542a6c5\"},\"headline\":\"RC2026 \u2013 Part 4 \u2013 Reading the temperature from a BME280 on an RC2014\",\"datePublished\":\"2026-10-29T12:21:34+00:00\",\"dateModified\":\"2026-10-29T12:21:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\\\/\"},\"wordCount\":693,\"image\":{\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/assets\\\/BME280-RC2014.jpg\",\"keywords\":[\"BME280\",\"RC2014\",\"RC2026\",\"SPI\"],\"articleSection\":[\"RC2014\",\"RC2026\",\"RetroChallenge\"],\"inLanguage\":\"en-GB\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\\\/\",\"url\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\\\/\",\"name\":\"RC2026 \u2013 Part 4 \u2013 Reading the temperature from a BME280 on an RC2014 - Robert Price\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/assets\\\/BME280-RC2014.jpg\",\"datePublished\":\"2026-10-29T12:21:34+00:00\",\"dateModified\":\"2026-10-29T12:21:35+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/#\\\/schema\\\/person\\\/fac6d5b076e0e14e1fb13e15b542a6c5\"},\"description\":\"Reading the temperature using a BME280 sensor attached to an RC2014 Z80 computer. The code is bit-banging the SPI protocol to retrieve data.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\\\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/assets\\\/BME280-RC2014.jpg\",\"contentUrl\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/assets\\\/BME280-RC2014.jpg\",\"width\":1600,\"height\":1200},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"RC2026 \u2013 Part 4 \u2013 Reading the temperature from a BME280 on an RC2014\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/#website\",\"url\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/\",\"name\":\"Robert Price\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/#\\\/schema\\\/person\\\/fac6d5b076e0e14e1fb13e15b542a6c5\",\"name\":\"rob\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g\",\"caption\":\"rob\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"RC2026 \u2013 Part 4 \u2013 Reading the temperature from a BME280 on an RC2014 - Robert Price","description":"Reading the temperature using a BME280 sensor attached to an RC2014 Z80 computer. The code is bit-banging the SPI protocol to retrieve data.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.robertprice.co.uk\/robblog\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\/","og_locale":"en_GB","og_type":"article","og_title":"RC2026 \u2013 Part 4 \u2013 Reading the temperature from a BME280 on an RC2014 - Robert Price","og_description":"Reading the temperature using a BME280 sensor attached to an RC2014 Z80 computer. The code is bit-banging the SPI protocol to retrieve data.","og_url":"https:\/\/www.robertprice.co.uk\/robblog\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\/","og_site_name":"Robert Price","article_published_time":"2026-10-29T12:21:34+00:00","article_modified_time":"2026-10-29T12:21:35+00:00","og_image":[{"width":1600,"height":1200,"url":"https:\/\/www.robertprice.co.uk\/robblog\/assets\/BME280-RC2014.jpg","type":"image\/jpeg"}],"author":"rob","twitter_card":"summary_large_image","twitter_misc":{"Written by":"rob","Estimated reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.robertprice.co.uk\/robblog\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\/#article","isPartOf":{"@id":"https:\/\/www.robertprice.co.uk\/robblog\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\/"},"author":{"name":"rob","@id":"https:\/\/www.robertprice.co.uk\/robblog\/#\/schema\/person\/fac6d5b076e0e14e1fb13e15b542a6c5"},"headline":"RC2026 \u2013 Part 4 \u2013 Reading the temperature from a BME280 on an RC2014","datePublished":"2026-10-29T12:21:34+00:00","dateModified":"2026-10-29T12:21:35+00:00","mainEntityOfPage":{"@id":"https:\/\/www.robertprice.co.uk\/robblog\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\/"},"wordCount":693,"image":{"@id":"https:\/\/www.robertprice.co.uk\/robblog\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\/#primaryimage"},"thumbnailUrl":"https:\/\/www.robertprice.co.uk\/robblog\/assets\/BME280-RC2014.jpg","keywords":["BME280","RC2014","RC2026","SPI"],"articleSection":["RC2014","RC2026","RetroChallenge"],"inLanguage":"en-GB"},{"@type":"WebPage","@id":"https:\/\/www.robertprice.co.uk\/robblog\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\/","url":"https:\/\/www.robertprice.co.uk\/robblog\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\/","name":"RC2026 \u2013 Part 4 \u2013 Reading the temperature from a BME280 on an RC2014 - Robert Price","isPartOf":{"@id":"https:\/\/www.robertprice.co.uk\/robblog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.robertprice.co.uk\/robblog\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\/#primaryimage"},"image":{"@id":"https:\/\/www.robertprice.co.uk\/robblog\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\/#primaryimage"},"thumbnailUrl":"https:\/\/www.robertprice.co.uk\/robblog\/assets\/BME280-RC2014.jpg","datePublished":"2026-10-29T12:21:34+00:00","dateModified":"2026-10-29T12:21:35+00:00","author":{"@id":"https:\/\/www.robertprice.co.uk\/robblog\/#\/schema\/person\/fac6d5b076e0e14e1fb13e15b542a6c5"},"description":"Reading the temperature using a BME280 sensor attached to an RC2014 Z80 computer. The code is bit-banging the SPI protocol to retrieve data.","breadcrumb":{"@id":"https:\/\/www.robertprice.co.uk\/robblog\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.robertprice.co.uk\/robblog\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\/"]}]},{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/www.robertprice.co.uk\/robblog\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\/#primaryimage","url":"https:\/\/www.robertprice.co.uk\/robblog\/assets\/BME280-RC2014.jpg","contentUrl":"https:\/\/www.robertprice.co.uk\/robblog\/assets\/BME280-RC2014.jpg","width":1600,"height":1200},{"@type":"BreadcrumbList","@id":"https:\/\/www.robertprice.co.uk\/robblog\/rc2026-part-4-reading-the-temperature-from-a-bme280-on-an-rc2014\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.robertprice.co.uk\/robblog\/"},{"@type":"ListItem","position":2,"name":"RC2026 \u2013 Part 4 \u2013 Reading the temperature from a BME280 on an RC2014"}]},{"@type":"WebSite","@id":"https:\/\/www.robertprice.co.uk\/robblog\/#website","url":"https:\/\/www.robertprice.co.uk\/robblog\/","name":"Robert Price","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.robertprice.co.uk\/robblog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":"Person","@id":"https:\/\/www.robertprice.co.uk\/robblog\/#\/schema\/person\/fac6d5b076e0e14e1fb13e15b542a6c5","name":"rob","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/secure.gravatar.com\/avatar\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g","caption":"rob"}}]}},"_links":{"self":[{"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/posts\/3407","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/comments?post=3407"}],"version-history":[{"count":7,"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/posts\/3407\/revisions"}],"predecessor-version":[{"id":3425,"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/posts\/3407\/revisions\/3425"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/media\/3387"}],"wp:attachment":[{"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/media?parent=3407"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/categories?post=3407"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/tags?post=3407"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}