Page 1 of 3
This is an extract from my new book Programming the Raspberry Pi Pico In C and it presents a PIO program for the 1-Wire bus – the DS18B20 to be precise.
Programming the Raspberry Pi Pico In C
By Harry Fairhead
Buy from Amazon.
- Chapter 1 The Raspberry Pi Pico – Before We Begin
- Chapter 2 Getting Started
- Chapter 3 Getting Started With The GPIO
- Chapter 4 Simple Output
- Chapter 5 Some Electronics
- Chapter 6 Simple Input
- Chapter 7 Advanced Input – Events and Interrupts
- Chapter 8 Pulse Width Modulation
- Chapter 9 Controlling Motors And Servos
- Chapter 10 Getting Started With The SPI Bus
- Chapter 11 A-To-D and The SPI Bus
- Chapter 12 Using The I2C Bus
- Chapter 13 Using The PIO
Extract: A 1-Wire PIO Program ***NEW!
- Chapter 14 The DHT22 Sensor Implementing A Custom Protocol
- Chapter 15 The 1‑Wire Bus And The DS1820
- Chapter 16 The Serial Port
- Chapter 17 WiFi Using The ESP8266
- Chapter 18 Direct To The Hardware
The 1‑Wire bus is a proprietary bus that is very easy to use and has a lot of useful devices you can connect to it, including the iButton security devices, memory, data loggers, fuel gauges and more. However, probably the most popular of all 1‑Wire devices is the DS18B20 temperature sensor – it is small, very cheap and very easy to use. This chapter show you how to work with it, but first let’s deal with the general techniques needed to work with the 1‑Wire bus.
Programming in C on the Pico gives you more than enough speed to implement a bit-banging driver, which for many purposes is sufficient. However, the 1-Wire protocol is easy enough to implement using the PIO. In this chapter we look at the basic ideas of the 1-Wire bus, implement a bit banging program for its most popular device and extend this to a PIO program.
In Chapter but not in this extract.
- The Hardware
- Writing Bits
- A First Command – Writing Bytes
- Reading Bits
- Computing The CRC
- The DS18B20 Hardware
- Initiating Temperature Conversion
- Reading the Scratchpad
- Getting The Temperature
- A Temperature Function
- The Complete Program
A PIO DS18B20 Program
Implementing the 1-Wire protocol using a PIO is one of the most difficult tasks we tackle. It needs to both send and receive data and the master has to provide the start pulse for the slave to send data. The specification also makes it seem that we have to use a conditional to vary the timing of the data part of the pulse depending on sending a one or a zero. This is a lot of logic to fit into 32 instructions. In addition a 1-Wire device can send far more data than the FIFO can hold. At first appraisal the idea of implementing the 1-Wire protocol in a PIO program seems hopeless, but with a shift in emphasis it can be made easier.
The main operations that you need to work with a 1-Wire device is to send a set of bytes and receive a set of bytes. In general, the timing requirements of the 1-Wire bus are at the bit level. That is, when you read data the device will generally store the data until you are ready for it. This means that if you can implement a byte read/write in the PIO then the main program can get on with something else while the 1-Wire device processes data. If the main program is interrupted then no harm is done as it can expect the PIO to continue to process the next byte ready for when it returns.
What all of this implies is that all we really have to do is implement a bit send and a bit receive facility. Using the way that 1-Wire protocol is usually described, this would be very difficult. In other words, trying to implement the simple-minded bit-banging protocol as a PIO program isn’t going to work. A slightly different interpretation of the protocol, however, makes it very possible. If you think of each bit frame as starting with a short low pulse which signals the start of the frame, then a zero sends a low after the initial pulse and a one sends a high. In other words, we can implement the write protocol as:
- Send short “start bit” of about 6µs
- Send the data bit for the rest of the frame – about 60µs
- Set the line high for 10µs as a spacer between bit frames
The read protocol is much the same:
- Send short “start bit” of about 6µs
- After about 9µs sample the line and use this as the read bit
- Do nothing for about 55µs as a spacer between bit frames
In this form the protocol doesn’t need conditionals as the sending of a zero or a one and the receiving of a zero or a one follows the same steps.
Using this version you could simplify the logic of the bit-banging example given earlier, but there is no real need to as there is plenty of space and computational power – using a PIO is a very different matter and regularity in the implementation of a protocol is important.
There is also the problem of how to implement the PIO program so that the C program can make use of it. One possibility is to use one state machine for send and other to receive, but it is possible to create a single program to to do both jobs.