My Pi Description

My Experiences With the Raspberry Pi -- Tracking My Learning -- My Pi Projects

Sunday, August 4, 2013

Gertboard Project - Camera Remote Control - Introduction

I have a remote control device for my camera that consists of a receiver and a hand-held transmitter. Wouldn't be great to have a motion detector trigger the camera using this remote control receiver? I could also take exposures at timed intervals without my being near the camera. The Pi and the ATmega microcontroller on the Gertboard provided most of the hardware to do the job. I only needed to add a $10 motion detector from Adafruit, and a four dollar 433MHz RF transmitter from Sparkfun.
I have not made an enclosure so everything is just loose wires and components. When using the motion detector, once the ATmega microcontroller is programmed, the Pi can be disconnected. Just a source of 3.3V will be required. While the Pi and Gertboard combination is a good development platform, a standalone project that does not require a user interface would be much simpler. Adafruit has a couple of ATmega32U4 development boards that are tiny, cost only $20 and can be programmed over USB. Check out this one, and this one.
This is what my Pi-Gertboard combination looks like now:
Tangle of stuff to Remotely Control My Camera From a Motion Detector
I have a Canon RF remote control receiver and transmitter combination. It works with Canon's digital SLRs and their G series cameras. Luckily, the documentation that came with the remote control gave me the frequency of the RF devices. It is 433MHz, which, I believe, is more commonly used in Europe. References to the frequency of these devices seem to be reported as 433MHz or 434MHz. Most RF remote control devices manufactured in the US use 315MHz. Sparkfun also supplies receivers and transmitters for 315MHz.
The following is a block diagram of the setup showing only what I thought was necessary to show. You may wish to click on the image to see the fine details.
Block Diagram
The next post will report on how I ascertained the information the remote control transmitter sends to the remote control receiver to control the camera. Subsequent posts will present the code to control the camera using the ATmega microcontroller.

Thursday, July 25, 2013

Gertboard - Modifying the Board

Modified Circuit For Buffers Without Switches (Nine Circuits)
Modified Circuit for Buffers With Switches (Three Circuits)
To modify the Gertboard, I added a 4.7k pulldown resistor to each of the lower (lower according to the schematics above) buffers to keep their LEDs normally off and to provide anti-static protection. 100k pullup resistors were added to each upper (upper according to the schematics above) buffers for anti-static protection.
Modifications To The Bottom Of Gertboard.
The modifications were made by soldering surface mount resistors to the underside of the Gertboard. The resistors were of the 1206 size - 0.12" x 0.07" x 0.02" thick. These are about the smallest parts I can solder by hand. The 4.7k resistors (pulldowns to lower buffers) are soldered between adjacent pins of J10. This was fairly easy as the distance between these pins was 0.1". Refer to the photograph above this paragraph. You can see these resistors along the bottom edge.
Soldering the 100k resistors was a little more difficult since this was done at the ICs pins themselves. A copper wire was soldered to pins 20 of the ICs. The resistors were soldered between these copper wires and pins 2, 4, 6, and 8 of the ICs. You can see these connections in the photograph above. I suggest you use the single strand, 30 AWG, wire-wrap wire for this purpose. This is available from Sparkfun for about $9 for 100ft.
If you are using any of the three switches on the Gertboard, the 100K resistors are sufficient to pull the level up to 3.3V when the switch is not pressed. Therefore, it is not necessary to use the Raspberry Pi's internal pull-ups.

Monday, July 22, 2013

Gertboard - What the Heck! Why are those LEDs Flashing On and Off?

So, I unpacked the Gertboard, attached the stand-offs, connected it to the Raspberry Pi, and applied power.
And - All twelve LEDs on the Gertboard lit, then some went off, then different ones just started to flash on and off. When I touched the metal shell of the Ethernet, USB, or HDMI connectors all of the LEDs went off.
THAT'S JUST WRONG. ALL LEDs SHOULD BE OFF UNLESS COMMANDED TO BE ON.
I looked at the schematics to find if there was a fault with the Gertboard. Did I find a problem? Yes a DESIGN problem. Refer to Figure 8 on page 15 of the "Gertboard User Manual" (version 2 manual). I have recreated that figure here except for the 10K pullup resistor. I'll talk about that below the diagram.
Buffer and LED circuit. Represents one of twelve circuits
Now here is where things get a bit tricky. If you look at that figure 8 in the manual, you see a 10k resistor connected between the input of the lower buffer and 3.3V. Why doesn't my diagram above show that resistor? When I purchased my Gertboard, only version 1 of the user's manual was available. I didn't know there was a new version until I started to write the post before this one. The version 1 manual, and schematics did not show this resistor. I did not know these resistors (R201 - R212) even existed on my board. Even so, the combination of the 10k pullup resistor and the 74HC244 buffer chip did not do the job. The 10k was not strong enough of a pullup (10k is too high a value) to prevent the LEDs from randomly turning off when no jumpers or wires connect the buffers to other circuitry.
The version 1 manual did talk about the problem. It said, "Depending on the type of 74xx244 buffer chosen, the LED could behave randomly if the port is not driven properly. In that case it may easily switch state, switching on or off with the smallest of electronic changes, for example, when the board is simply touched." That was what I saw even with the 10k pullup resistor. The text says that you need to drive the port properly. If your project only needs one port, then the other eleven are not being driven at all. Is it proper operation to have to look at eleven LEDs flash on and off? Version 2 of the manual changes that information to: "The resistor on the right side of Figure 8 is a pull-up. If it were not there, the LED would turn off and on with the smallest of electronic changes, for example, when the board is simply touched. Turning the LED on when it is not being driven prevents this seemingly random behaviour and also serves as an indicator that your Gertboard is receiving power properly. Note that if the output jumper is installed but the ‘Raspi’ point is not driven, the random behaviour will return."
Even if the pullups worked and the LEDs connected to the unused buffers turned on, that to me, is not proper operation. If a circuit is not being used, the LED should be OFF. The manual says that the LEDs being on indicates "that your Gertboard is receiving power properly". Do we need up to 12 indicators that the board is under power?
There is another issue when no jumper or wire connects the input of a buffer to anything else. The buffer IC is a CMOS device. These devices are highly susceptible to destruction by static electricity. If the inputs are not connected to anything except to a connector pin, a pullup resistor is always connected to the input. This provides protection when the connector is not connected to anything else. Often an IC has multiple, identical, circuits. For example, the 74HC244, has eight buffers. If your circuit only needs 7 buffers, the eighth one will always have a pullup resistor (or, if you are the circuit designer, you get fired). For this purpose, a value of about 100k is acceptable. You probably have noticed that electronic circuit boards, like the Gertboard and the Raspberry Pi, are packed on foam and in one of those ubiquitous black bags. That foam and that bag are to prevent static electricity from reaching the board and blowing up ICs when the board is not connected into a circuit.
The Gertboard greatly exacerbates this static problem because of the way it is used. The human body is a great source of static electricity discharge. You, the user of the Gertboard, will be handling the board, connecting and disconnecting the Pi, and installing and removing jumpers, wires, and devices. The board does not have to be under power for damage to occur.
OK, there are 10k pullup resistors on the board - in fact there are 12 of them. However, there are TWENTY FOUR BUFFERS, not just 12. In the figure above, the input of the buffer on the bottom, the one that connects to the LED has the 10k pullup - so should be protected from static discharge. But, what about the upper buffer? According to the schematic it looks like the input of that buffer connects to the Raspberry Pi. That is only correct if you use a wire and connect that point to the Pi (make a connection between a J2 and a J3 pair of pins). If you don't, that input is not connected to anything except a connector pin, which is not connected to anything else. Don't forget that this diagram represents one of 12 circuits. Chances are that you will not always be using all 12 of these circuits in your projects.
My next blog post will tell what I did about this problem.

Friday, July 19, 2013

The Gertboard - What Is It?

Gertboard Connected to Raspberry Pi
The Gertboard extends the usefulness of the Pi by allowing a variety of devices to be connected to the Pi, and, thus be controlled by the Pi. It is made up of individual circuits that have connector pins at their inputs and outputs. These circuits are connected to each other, to the Pi's GPIO pins, or to external devices. Jumpers are used to connect adjacent connector pins, and wires, with a socket on each end are used for other connections. Please note the colored wires in the photo above.
The Gertboard is available from SparkFun for $53 (USD). Newark Electronics has it for $50. Adafruit does not seem to carry it.
As is usual with most things you buy for the Pi (and the Pi, itself) the Gertboard does not come with any documentation. Yes, it ships with a CD, but that is simply a marketing tool to sell ARM development software. There is, however, a very comprehensive user's manual that explains every circuit. All circuits have at least one test routine. The manual shows how to connect the circuits for each test and explains the test software. The test software, in C++ and Python must be downloaded to the Pi. The manual details how to get, and install that software. Even though the user's manual references the schematic diagram for the board, these schematics are not included in the manual. However, these schematics are available as a separate file. The best way to get both the user's manual and the schematics is from the SparkFun page. So click here.
Gertboard - Illustration from "Gertboard User Manual". I added "Proto Area" to the illustration
So what are the features of the Gertboard?
  • The Gertboard plugs onto the GPIO connector of the Pi. Because the Gertboard's GPIO bottom facing connector socket connects directly to the top facing pins of the Pi's connector, it forms a single, physically stable, unit consisting of the two devices (see note below).
  • Twelve buffers for inputs to the Pi and twelve buffers to drive outputs from the Pi. Input buffers protect the Pi from inputs like sensors while output buffers reduce the loading of the Pi by output devices (like LEDs).
  • 12 LEDs
  • 3 Momentary push button switches
  • 6 High Voltage/High Current Outputs (open collector drivers). Each of these circuits can drive half an amp at 50 volts
  • A fused motor controller. Uses the pulse width modulation (PWM) capabilities of the Pi to control the speed and turning direction of the motor. This circuit can drive 2A at 18V.
  • Two 8 bit digital to analog (D to A) circuits.
  • Two 10 bit analog to digital (A to D) circuits.
  • And best of all an Atmel ATmega328 microcontroller IC. This is the same microcontroller as used by Arduino boards. Gordon Henderson, of Drogon Systems has developed all of the methods and procedures to interface the microcontroller to the Pi. The instructions to obtain all of the software, including the Arduino IDE (Integrated Development Environment) are provided by Gordon. To write programs (in C++) on the Pi for the Atmega328, and to get those programs loaded in the Atmega328, you use the Arduino IDE running on the Pi. The Gertboard User Manual provides the link to Gordon's web page. The Arduino IDE provides many sample programs and C++ help to get you started.
  • Prototyping area (outlined in blue in the figure above) to wire in your own circuitry. You will see where I use this area in my next blog post.
I have version 2 of the Gertboard. As I mentioned above, the Gertboard and the Pi connect directly together. This is not true for version 1. Version 1 requires a ribbon cable to connect to the Pi. I believe only Version 2 is available now. Version 1 came as a kit requiring the purchaser to assemble and solder parts to the board. Version 2 cones completely assembled. Version 1 used thru-hole parts with all IC's in sockets. Version 2 uses mostly surface mounted parts. In version 2, most IC's are thru-hole but only one IC, the ATmega microcontroller is in a socket. The other ICs are soldered to the PC board.

Thursday, July 4, 2013

A Pi In The Fridge

I did find a practical use for the the temperature measurements using the Pi (see my past several blog posts). We thought the temperature in our refrigerator was a bit too high. To check it out, I put the Pi with the DS18B20 temperature sensors in the refrigerator. The Pi was powered by SparkFun's solar charger and battery back. The Pi was on a lower shelf while the cable sensor was in a glass of water on an upper shelf. The whole assembly was in the refrigerator for several hours. It all worked well at the temperature that got down to just under 40F (a little too warm for the food though).
Raspberry Pi on Lower Shelf of Refrigerator
The lower left corner of the switch (white square with the 4 printed on it) is pointing to the DS18B20 To-92 sensor. It's just a small black blob in the photo (not one of my best photographs. I didn't want to hold the refrigerator door open too long to get that perfect shot). The three pin connector for the DS18B20 cable sensor is just under the TO-92 sensor. I made that little connector to interface the three leads of the cable to the breadboard.
Probe In Glass of Water - Hunk of Cheese Holding Cable in Place

Tuesday, June 25, 2013

A Raspberry Pi Thermometer - My Software To Display Temperature

Let's back up for a moment. Two posts ago, I indicated that the Raspbian and Occidentals distributions have support for the 1-Wire interface and the DS18B20 temperature probes. We see this implemented in the kernel modules w1-gpio and w1-therm. I said that the only support I knew of was to read the temperature, and that you could not write to the device to change the resolution or set temperature limits. There is one other limitation I forgot to mention: You can only use GPIO 4 to interface the device to the Pi - no other choice is possible.
I wrote a python script using my two temperature sensors. It takes repeated measurements but is not greatly practical as it does not store the measurements. I'm going to add that capability next. I guess I'll start by writing the results to a file. I'm going to investigate RRDTool which is a way to put the results into a database. The program includes graphing capabilities, which sounds fascinating.
I kind of overloaded my script with a lot of stuff, because, after all, I'm doing this to learn. I don't really have a pressing need to make temperature measurements. I do this for fun. Luckily, I don't have to program to please a client, or employer, or to comply with any deadline. The Pi, along with python programming, is just an adult toy.
Functionally, the script asks the user how frequently to make measurements and which of the two probes to use. The program outputs each measurement to the terminal screen along with the date and time and the sensor choice. It also outputs the temperature, along with the date and time, to my 16 character by 2 line LCD display. The user terminates the script by issuing a keyboard interrupt (CTRL-C) or by pressing the button on the breadboard. The script then tells you when you started the run and the duration of the run. Here is a sample from a very short run:
Screen Shot of Terminal Output After a Short Run of the Script
Readout on the LCD Display
Without further ado, here is the script:
I would like to talk about what I find interesting about the script. I'll take it from the top and work down.
Lines 17 - 23: We need to import quite a few modules. I'll come back and talk about the commented out module in line 19 later. Line 23 is the module I wrote that has the functions to control the 16X2 LCD display. You can see this code on my blog entry "16 X 2 LCD Base Code" of March 23, 2013.
Lines 25 - 36: Here's a bit of extravagance. The only lines here that are necessary are lines 34 and 35. All the other lines in the function are superfluous. This function looks to see if the two modules w1-gpio and w1-therm are loaded in the kernel. If not, it loads them. When you load the modules, run the script. and then terminate the script, the modules stay loaded in the kernel. If you run the script again, it's OK if the script says to load them, if they are already loaded. My checking to see if they are loaded is unnecessary. But, I'm not doing this for a living, so a few extra lines is no big deal.
When I saw lines 34 and 35 in every other python program dealing with the DS18B20, I was very curious about that Linux command "modprobe". What did it do? I found this site.It has everything I needed to know: how to load modules, remove modules, and see what modules are present in the kernel. I wanted to use this information in my script, thus all those extra lines.
The loadmodules function demonstrates two methods to run a Linux command in Python. One uses the Popen method in the subprocess module (line 29), and the other uses the system method in the os module (lines 34 and 35). The second method is useful for commands that do not return anything you are interested in knowing about. It would be the one to use if you wanted to run "cd" to change directory. If you wanted to list the contents of the directory using "ls", the Popen would be the one to use. To see if the w1-gpio and wi-therm modules are loaded we issue the "lsmod" command, which lists the loaded modules like "ls" does for directories and files. The output is redirected to the stdio using the "stdio = subprocess.PIPE" optional argument. In the same way, we redirect any error to the stdio.
There appears to be an error in either line 31 or lines 34/35. But they are correct. If the two modules are loaded, the output of "lsmod" shows the module names with the underscore. When we load the modules, we use the dash in the names. Strange.
Lines 38 - 67: This function is rather long because it captures the occurrences of the w1-slave file failing to open. I talked about this in previous posts. If that glitch never occured, only six lines would be necessary (38, 47, 48, 63, 64, and 65). We use the Popen method to read the two line w1-slave file in line 47 (see the last post to see examples of these two lines). The output is redirected to the stdio and we read the contents in line 48. We do not have to bother to close the file. Lines 47 and 48 are a good alternative to using the open command, followed by the read command, and the close command. Note in line 48, we also read any error, such as ".....file not found" and can easily deal with the error. Using the open command, if the file is not found, then an exception is thrown and we have to handle that exception. Not a big deal, but the Popen approach seems much more efficient.
If an error occurs, my approach to recover is to unload the modules using the modprobe -r command and then reload them after a short delay. I wait 10 seconds at the end to give plenty of time for the modules to load. I tried to recover from the error by simply rereading the file (reissuing the Popen command), but that did not work. Once the error occurred, it kept occurring until the script was terminated. Unloading and reloading the modules does seem to work. I only do the unload and reload module process three times. If there is still an error, the script stops, by the statement raise(IOError). We'll talk about this statement when we discuss the main program. For my own information, I keep track of the occurrences of w1-slave failing to open in the variable glitches.
Lines 69 - 83: The print2display function simply takes the current time and the temperature and outputs the former to line 1 and the latter to line two of the LCD display. I found that those 10ms. delays were required to keep the display from going berserk after a time.
One of the fun aspects of this project was playing with the methods in the datetime module. The current time is determined by the now method in the datetime.datetime module and passed to the print2display function. The strftime method is a way to format the time in a variety of ways. Look here at section 8.17. in the Python documentation.
Lines 85 - 104: This is another example of throwing something in for the fun of it. Before the program terminates I wanted to print the duration of the run. Why do this? Simply because I wanted to figure out how to do it. I had read about the method timedelta in the datetime module in the Python documentation but could not understand it. That was because I thought timedelta took two date/times and reported the difference - just what I wanted. I was wrong, timedelta applies a time difference to a date/time, and reports a new date/time. I did make use of timedelta in the commented out line 92. More on this later.
At the beginning of the main part of the program I save the current time in the variable starttime. To use starttime in my function, I declared it a global variable. I could have easily passed the value of starttime to the function totaltime. I have a feeling that would have been the preferred method. To find the elapsed time, I simply subtract the starttime from the time at the end of the run and make a string of the result.
Now is a good time to discuss the commented out line 92 and the commented out line 19. I left those lines in the script for the purpose of discussing testing. You should test as much of your scripts as possible to assure they will work under various circumstances, and, for this script, will work with long duration runs. The string in line 97, the value of elapsedtime can look very different if the run time is over or under a day. Let's say the run time was 23 hours, 59 minutes, and 59.99 seconds. The string value of elapsedtime will be '23:59:59.990000'. If the run duration is one minute longer, elapsedtime looks like this: '1 day, 0:00:59.990000'. Quite a bit different. For testing this, I didn't want to make a run of over one day, so that's is where I used line 92. Using timedelta, I just added 24 hours to elapsedtime to get the string with the 1 day in it. Worked like a charm. You can see how I parsed the string value of elapsedtime to print the time in days, if needed, then hours, minutes, and seconds.
Lines 106 - 116: There is a momentary switch on the breadboard (that square job with the number 4 printed on it). It's purpose, here, is to provide a second way to exit the script. Checking the switch position is a matter of looking at the GPIO pin connected to the switch. If it is a logic high, the switch is not pressed (pin is pulled up by a resistor to 3.3V). Pressing the switch grounds the pin. If the function sees the pin low, it waits 200ms. and looks again. If the pin is still a logic low, it assumes the switch is really being pressed. The final action is the statement raise(KeyboardInterrupt). I'll reserve comment about this until later.
The Main Program:
Lines 131 - 137: One of the elements I really wanted to incorporate into my script was error handling, and error creating. These seven lines are a small manifestation of error handling which is implemented with the try and except statements. When a script encounters an error that is not "handled" within the script, it just stops and you receive an error message. The try and except statements are what you use to "handle" error messages. If an error occurs while processing the try block (the indented code below the try: statement), execution moves from the try block to the except block. Once the code in the except block is executed, execution moves to the code beyond the except block. For example, when asked to input a value to measurement_interval you input a letter rather than a number. Without the error handling, python will stop the script because measurement_interval expects a float, not a string literal. Python throws an exception, and prints: "ValueError: could not convert string to float" Since we don't want the program to stop because of a simple keystroke error, we trap the error by executing the except block. That block has the one word command of "pass", which means do nothing. The except block must have something in it, so "pass" suffices. So, if you press a letter instead of a number, absolutely nothing happens and you go back to the beginning of the while loop. Once you enter any number, including zero, you exit the loop with the break command with a good value for measurement_interval.
Line 125: These are the sub-directories representing my two temperature sensors. The first one is the breadboard sensor while the second one is on the end of the cable. Since this is all a learning experience, and I was reading about dictionaries, I was going to make this line: device_id = {breadboard: "28-00000400d39d", cable: "28-000004986cbb"}. But, I didn't get around to it. Tuples are pretty efficient though.
Lines 152 - 187: Here is the main loop of the script. I want to discuss the error handling first. The entire while loop is a try block so if any error occurs while executing within the loop, including execution within one of the functions, execution will jump out of the try block (thus out of the while loop) to one of the except blocks following the try block. The first two except statements look for specific errors. The first except statement looks for a keyboard interrupt, as you get by typing CTRL-C. This is one of the two normal ways I have provided to end the script. If, indeed CTRL-C was pressed, the code within that first except block (line 178) is processed and execution passes to line 189, bypassing the next two except blocks.
When executing the read_temp_raw function, if after three attempts we fail to open the w1-slave file, we get to the statement: raise(IOError) (line 67). The raise statement actually creates an error, in this case, IOError. If that indeed occurs, we jump out of the read_temp_raw function, out of the while loop in the main program, and land in the except(IOError) block. After executing the two print statements, we jump to line 189.
If some other, unanticipated, error occurs, execution passes out of the try block, bypasses the first and second except blocks, and lands in the third except block. Any error except a keyboard interrupt, or an IOError will be processed by that bare except statement. The print statement says we have an unexpected error and prints out what that error is. Once this is done, we move to line 189.
Within the while loop
Now let's look within the while loop. If the read_temp_raw function can open w1-slave, it returns the two line contents of w1-slave as a two element list. We check to see if the first line ends in 'YES'. If it does not, which seems to be the case about half the time, we wait a short time (the value of the variable short_wait) and go back to the beginning of the while loop to try again with a new read of w1-slave. If we do find a 'YES' we get the contents of the end of the second line following 't='. If 't=' is not found (rare if ever), we do like we do if 'YES' is not found: simply wait a short time and return to the top of the while loop and try again. If we do find 't=' we read the five digit number following it. That number is divided by 1000 to get the temperature in Centigrade and then converted to Fahrenheit.
After the temperature is found the current time is determined. The temperature and time along with the probe in use is printed to the screen and sent to the print2display function. It was rather a fun endeavor to come up with that print statement. I talked about the string formatting method, strftime, previously. Finding the unicode value ((hex B0) for the degree character was a challange. Finally, the time to wait between measurements is set to the value of measurement_interval inputted by the user.
Previously, I had the code to check the switch in the while loop in the main part of the program. Also, the wait between measurements was implemented, simply, with a sleep statement with the value of measurement_interval. This meant that if measurement_interval was a long time, in minutes or hours, I would have to press the switch at exactly the right time to catch the code outside of the sleep time, or press the switch for a long, long time. With the code in lines 170 - 174, I check the switch every second so the longest time to press the switch before the script stops is one second (actually 1.2 seconds to account for the wait statement in the check_switch function). It is necessary to check the switch in line 170 before getting into the small while loop in case the user selected zero seconds for measurement_interval.
I have just discovered a glitch in this script. If the user selects a negative number or a non-whole number for measurement_interval, that while loop will never get to exactly 0. I'll have to fix that. I should have tested for that before
Finally, how does the switch provide an exit from the script? It does so by the raise(KeyboardInterrupt) statement in line 116. If the switch is pressed, the effect is the same as if the user typed CTRL-C.

Monday, June 24, 2013

A Raspberry Pi Thermometer - Interpreting the Data

The W1-gpio and W1-therm modules create the following directory structure: /sys/bus/w1/devices followed by a directory tree for each 1- Wire device on the bus. These directory names are ids of the devices in hex. The DS18B20's ids start with 28-, so the two directories of my devices have the names 28-00000400d39d and 28-000004986cbb. Each of these directories contain a file called w1_slave. When queried, the DS18B20 returns 9 bytes of data which is placed into the w1_slave file. We get our temperature by reading this file.
w1_slave is not a file like a text or python file. Successive reads can contain different data, but the modified date/time of the file does not change. It's modify date/time reflects the date/time that the W1-gpio and W1-therm modules were loaded into the kernel.
Let's take a look at the contents of the w1_slave file. The following consists of two successive readings of that file using the cat command:
Notice the top line, everything before the "crc=". This is the output from the device in hex. The first two bytes represents the temperature in LSB followed by the MSB. Here, the temperature is 0166h. Convert that to decimal and multiply that number by 62.5 and you get 22375 which you see on the second line after the "t=". Divide this number by 1000 to get the temperature, 22.375 in degrees centigrade. The last byte returned is the CRC (cyclic redundancy check) which is calculated by the device based on the other eight bytes. Following the "crc=" you have the CRC calculated by the software. If that matches the CRC returned by the device, the software says "YES", otherwise "NO".
Note the second reading of w1_slave. Here the file says "NO". Note that the CRC returned by the device is 2Dh as before, but the software calculates ECh. Also note that the seventh byte returned by the device is 2Ah not 0Ah. The sixth, seventh, and eighth bytes are called "reserved" in the DS18B20's documentation. No further details are given except that they can not be overwritten. The sixth byte is always FFh and the eighth byte is always 10h. It does not say what the seventh byte should be. But, I have noted that, usually, if there is a "NO" at the end of the first line, the seventh byte is 2Ah, if "YES" it is always 0Ah. I say "usually" because, once in a while, we get a really lousy return when reading w1_slave. It looks like this:
I indicated in my previous post that this reading of w1_slave "almost works", and I'm not talking about whether there is a "YES" or a "NO" in the file, but something worse. I can make 10,000, or 20,000, successive measurements by reading w1_slave, and the next attempt will fail. Python says the file does not exist, but when you look, the file is still there. A very frustrating problem. I "think" I have solved that problem by unloading and reloading the W1-gpio and W1-therm modules, within my programs, when this failure is detected.
Enough of this. The next post will reveal the python program I wrote to use these temperature sensors.