yyrkoon 250 Posted December 9, 2016 Author Share Posted December 9, 2016 BTW: sleep .2 is 200 ms sleep I know . . . or two tenths of a second william@beaglebone:~/dev$ time ./read-temp Device: 28-00000647ddf6 18.00C 18.06C 18.06C 18.06C 18.06C^C real 0m5.394s user 0m0.000s sys 0m0.072s So how does .000 usertime compare to .008 ? @@Rickta59 Come back lol . . .I spent nearly as much time in kernel that you spent in user space. Not exactly sure if that's a bad thing or not. [EDIT] actually nearly 10 times as much. But, and I'm assuming this has to do with my program runs a looser loop, thus ran longer, and time() + opendir() etc are sys calls which do land in kernel mode. Most of that is initial application setup that runs once, but I'm also opening and closing the file descriptor once every second. Which I'm not sure what you're doing there with echo . . . either way, it doesn't work on the beaglebone( Debian Jessie 8.6 ), and cat in place of echo doesn't work either. The script runs too fast to read from the sensor properly. So one thing to know about the DS18B20 is that it's data refresh rate can be anywhere between 100, and 750 milliseconds. Depending on how it's configured. I have not got aroudn ot figurering out how to configure the sensor through Linux, but I'm not sure I will either. Chances are pretty good ill only be reading the the sensor once every minute, maybe even more. So here is part of what strace has to say about your script: read(3, "20 01 4b 46 7f ff 10 10 fc : crc"..., 128) = 73 read(3, "", 128) = 0 close(3) What this tells me is that you probably need to use read_line() as it looks like it's only catching the first half of the output from the sensor. By the way, it also almost looks as the crc value is not correct either. But who knows what strace is doing there . . . Quote Link to post Share on other sites
spirilis 1,265 Posted December 9, 2016 Share Posted December 9, 2016 I'm a little embarrassed to admit, but, I had no idea the Linux 'sleep' command could take a decimal point..... always thought it had to use integers. Turns out it takes suffixes for 's' (seconds, the default), 'm' (minutes), 'h' for hours and 'd' for days too! DESCRIPTION Pause for NUMBER seconds. SUFFIX may be 's' for seconds (the default), 'm' for minutes, 'h' for hours or 'd' for days. Unlike most implementa? tions that require NUMBER be an integer, here NUMBER may be an arbitrary floating point number. Given two or more arguments, pause for the amount of time specified by the sum of their values. Quote Link to post Share on other sites
Rickta59 589 Posted December 9, 2016 Share Posted December 9, 2016 Ok so when I wrote the first script I didn't really know what the w1_slave returned, it was more an example of what you might do. I went and dug up what I think the w1_slave returns. Here is the format I think it returns, but I really don't know you will have to adjust for it Assumming it returns something like this: $ cat /tmp/bus/w1/devices/28-100000001/w1_slave 4b 01 4b 46 7f ff 05 10 e1 : crc=e1 YES 4b 01 4b 46 7f ff 05 10 e1 t=19065You could use this script: #!/bin/bash # read the w1-temp values # put each line1 and 2 into variables # parse and see if it is ready # if so read the raw value and round it to 2 decimals read_sensor() { SENSOR_FILE=$1 local __celsius_raw=$2 local __celsius_dec=$3 local __rc=$4 local indx=0; while IFS='' read -r temp; do case $indx in 0) line1=$temp;; 1) line2=$temp;; esac indx=$((indx+1)) done < $SENSOR_FILE ready=${line1/YES/,ready} if [ "${ready#*,}" == "ready" ] then local celsius_raw=${line2#*t=} local celsius_dec=$(echo "scale=2; ((${celsius_raw}+5)/1000.0)" | bc) eval $__rc="1" eval $__celsius_raw="'$celsius_raw'" eval $__celsius_dec="'$celsius_dec'" else eval $__rc="0" fi } # loop through all the sensors SENSOR_FILES=$(echo /sys/bus/w1/devices/28-*/w1_slave) while true; do for sensor_file in ${SENSOR_FILES}; do read_sensor $sensor_file c d rc if [ "$rc" == "1" ]; then echo "Raw=${c}" echo "Celsius=${d}" else >&2 echo -n "." fi done sleep 0.2 done; This one uses only one external command "bc" to convert the raw value to a rounded one $ time ./w1_poll.sh real 0m5.560s user 0m0.012s sys 0m0.008s -rick Also here: https://gist.github.com/RickKimball/926a6e638d6fea994384af4d8487078f Quote Link to post Share on other sites
yyrkoon 250 Posted December 9, 2016 Author Share Posted December 9, 2016 I'm a little embarrassed to admit, but, I had no idea the Linux 'sleep' command could take a decimal point..... always thought it had to use integers. Turns out it takes suffixes for 's' (seconds, the default), 'm' (minutes), 'h' for hours and 'd' for days too! DESCRIPTION Pause for NUMBER seconds. SUFFIX may be 's' for seconds (the default), 'm' for minutes, 'h' for hours or 'd' for days. Unlike most implementa? tions that require NUMBER be an integer, here NUMBER may be an arbitrary floating point number. Given two or more arguments, pause for the amount of time specified by the sum of their values. Yeah, been that way for a while now, with .1 being the lowest possible value. I still use usleep though for some reason I do not even know why. Familiarity I guess. Quote Link to post Share on other sites
yyrkoon 250 Posted December 9, 2016 Author Share Posted December 9, 2016 Ok so when I wrote the first script I didn't really know what the w1_slave returned, it was more an example of what you might do. I went and dug up what I think the w1_slave returns. Here is the format I think it returns, but I really don't know you will have to adjust for it Assumming it returns something like this: $ cat /tmp/bus/w1/devices/28-100000001/w1_slave 4b 01 4b 46 7f ff 05 10 e1 : crc=e1 YES 4b 01 4b 46 7f ff 05 10 e1 t=19065You could use this script: #!/bin/bash # read the w1-temp values # put each line1 and 2 into variables # parse and see if it is ready # if so read the raw value and round it to 2 decimals read_sensor() { SENSOR_FILE=$1 local __celsius_raw=$2 local __celsius_dec=$3 local __rc=$4 local indx=0; while IFS='' read -r temp; do case $indx in 0) line1=$temp;; 1) line2=$temp;; esac indx=$((indx+1)) done < $SENSOR_FILE ready=${line1/YES/,ready} if [ "${ready#*,}" == "ready" ] then local celsius_raw=${line2#*t=} local celsius_dec=$(echo "scale=2; ((${celsius_raw}+5)/1000.0)" | bc) eval $__rc="1" eval $__celsius_raw="'$celsius_raw'" eval $__celsius_dec="'$celsius_dec'" else eval $__rc="0" fi } # loop through all the sensors SENSOR_FILES=$(echo /sys/bus/w1/devices/28-*/w1_slave) while true; do for sensor_file in ${SENSOR_FILES}; do read_sensor $sensor_file c d rc if [ "$rc" == "1" ]; then echo "Raw=${c}" echo "Celsius=${d}" else >&2 echo -n "." fi done sleep 0.2 done; This one uses only one external command "bc" to convert the raw value to a rounded one $ time ./w1_poll.sh real 0m5.560s user 0m0.012s sys 0m0.008s -rick Also here: https://gist.github.com/RickKimball/926a6e638d6fea994384af4d8487078f Thanks Rick I appreciate the effort. You realize there are about 5million bash scripts for 1-wire and the rPI ? Some really nice ones too. Quote Link to post Share on other sites
Rickta59 589 Posted December 9, 2016 Share Posted December 9, 2016 Thanks Rick I appreciate the effort. You realize there are about 5million bash scripts for 1-wire and the rPI ? Some really nice ones too. I didn't actually look no. If there are, why are you writing another solution? Quote Link to post Share on other sites
yyrkoon 250 Posted December 9, 2016 Author Share Posted December 9, 2016 I I didn't actually look no. If there are, why are you writing another solution? I already told you why last night. That, and what you've seen is not all I'll be doing. Quote Link to post Share on other sites
Rickta59 589 Posted December 9, 2016 Share Posted December 9, 2016 # best solution $ while true; do for sensor_file in /tmp/bus/w1/devices/28-*/w1_slave; do echo "scale=2; $(cat ${sensor_file} | grep -E -o ".{0,0}t=.{0,5}" | cut -c 3- )/1000.0" | bc; done; sleep .5; done yyrkoon 1 Quote Link to post Share on other sites
yyrkoon 250 Posted December 9, 2016 Author Share Posted December 9, 2016 # best solution $ while true; do for sensor_file in /tmp/bus/w1/devices/28-*/w1_slave; do echo "scale=2; $(cat ${sensor_file} | grep -E -o ".{0,0}t=.{0,5}" | cut -c 3- )/1000.0" | bc; done; sleep .5; done Yeah there are a bunch of one liners out there. But as I'm not only going to be reading the file, and displaying the temp to screen. That was just me experimenting, and then "obsessing" to convert a C program to C++. So first off the final application I'll be writing will be for a client, billing them 3-4 hours for the software. Then probably an additional 1-2 hours for a setup script to make sure everything needed is in place. Then if not, install all the needed goodies. While I'm not quite sure what the client wants *YET* my idea is to log the data out via MQTT. Then it becomes a question of how often do we log. Here, I'm thinking we probably want a command line option variable between say 1-60 seconds. 1 second to create a temperature profile of the board, if needed. Then 60 seconds normal checking / logging. Maybe even an additional parameter to only log when the temperature is within a certain range. e.g. board is close to or is overheating, so start logging. With perhaps yet another parameter to tell the board to shutdown when overheating. There is even a web front end, as well as an iPhone/Android app in the works. At this point, writing a shell script probably is not ideal. Not to mention it'll get very messy quickly. Perhaps even slow. So for a one off board type project, DiY style. *MAYBE* a shell script. But there are multiple boards, nation wide, logging data out to a server <somewhere else> in the US. Think 10's of boards at this point (30-40) deployed, with around 50-60 total made so far. Just for one type of board, there are actually 3-4 variations for different situations, with only the first variation being deployed in the wild _right_now_. The original idea though( not mine, the clients ) is actually really cool, and innovative. Quote Link to post Share on other sites
yyrkoon 250 Posted January 23, 2017 Author Share Posted January 23, 2017 So coming back to this problem again, just now. I decided for my current purpose to use a shell script. Mostly because a shell script should be readable by most, that are familiar with UNIX like systems, and I'm not the only one maintaining this system. @@Rickta59 bc is a problem, because it does not come default with the current debian image we're working with. Sure I could install bc using APT, but why waste the effort and space ? I did create a simple solution though based off a couple of stackoverflow posts I searched for . . . root@beaglebone:~# temp=$(cat /sys/bus/w1/devices/28-*/w1_slave |awk ' /t=/ {print $10}') root@beaglebone:~# echo ${temp:2} 16812 This is of course fixed type, but I do not necessarily need a floating point type do I ? I don't think so . . . But going back to our discussion from before. Running cat on a 1-wire device, there is a very noticeable 2-3 second pause at the beginning. This pause, as I recall does not happen when I ran the C++ code mentioned previously. With that said, for the purpose I'm using this for. It doesn't matter. EDIT: If floating point did matter though . . . root@beaglebone:~# temp=$(cat /sys/bus/w1/devices/28-*/w1_slave |awk ' /t=/ {print $10}') root@beaglebone:~# awk "BEGIN {print ${temp:2}/1000}" 16.937 Quote Link to post Share on other sites
chicken 630 Posted March 12, 2017 Share Posted March 12, 2017 Here's some more C++ magic which seems applicable to embedded programming. I think he optimized for speed instead of space (using tons of mov instead of a loop to initialize sprite bitmaps). But a lot of impressive optimization by the compiler. On the downside, I didn't understand half the constructs he was using. I guess I need to relearn C++ via embedded.fm podcast yyrkoon and L.R.A 2 Quote Link to post Share on other sites
yyrkoon 250 Posted March 17, 2017 Author Share Posted March 17, 2017 On 3/12/2017 at 3:23 PM, chicken said: Here's some more C++ magic which seems applicable to embedded programming. I think he optimized for speed instead of space (using tons of mov instead of a loop to initialize sprite bitmaps). But a lot of impressive optimization by the compiler. On the downside, I didn't understand half the constructs he was using. I guess I need to relearn C++ via embedded.fm podcast Didn't know you posted, heh been super busy with the day job building a monitoring system for the company, in addition to building an update system( for our own software )from scratch . . . pretty interesting stuff, and I learned A LOT about systemd services + timers, but without actually getting into the architecture of it all. It's a nightmare trying to visualize all this in your head. Chicken, I've come to realize that that for myself, C is the only real way to go with embedded design. I personally find C++ good for when you need to use a lot of strings, and perhaps other various constructs, it can be ok to work with. But when you need all out performance, C will usually be the best option. Unless you're super proficient with C++, and you write all of, or at least all of the important code from scratch. Same goes for C though really. An example would be my two process application where I needed to share a file between the two halves, and I wrote my own binary file lock. Because the C std API calls were all way too slow. EDIT: Oh, and you can bet I will eventually get around to watching the video. chicken 1 Quote Link to post Share on other sites
chicken 630 Posted March 17, 2017 Share Posted March 17, 2017 I don't try to convince anybody. I'm way too busy myself to unlearn bare metal C. But I thought the video will be relevant for people that venture down the rabbit hole. yyrkoon 1 Quote Link to post Share on other sites
yyrkoon 250 Posted March 17, 2017 Author Share Posted March 17, 2017 15 minutes ago, chicken said: I don't try to convince anybody. I'm way too busy myself to unlearn bare metal C. But I thought the video will be relevant for people that venture down the rabbit hole. Sure, I get it. Like you, I guess I am just more used to using C most of the time, but I still like many aspects of C++, as well as other languages. It's kind of funny, I was watching a youtube video the other day before bed, and I forget the speakers name( He's pretty well known, I should remember his name, but I dont - I'm not a "fanboy" that way ), where he was explaining why C++ was what he considered the better choice for embedded software development. Then he showed a chart from the last 10-15 years. Which showed C graphing upwards, while C++ was trending downwards . . . Ah right, Dan Saks, but his contention is that C++ is better than C, and I completely disagree with that. I think every language has it's place, and for different people, that will skew one direction or another. But there is a reason why you will never, at least within the near future, see any C++ code in the Linux kernel. chicken 1 Quote Link to post Share on other sites
veryalive 49 Posted March 17, 2017 Share Posted March 17, 2017 The Dan Saks video is brilliant! Thank you for posting. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.