{"id":133,"date":"2015-02-13T23:46:52","date_gmt":"2015-02-13T23:46:52","guid":{"rendered":"http:\/\/www.fartmagnet.co.uk\/warmcat\/?p=133"},"modified":"2015-04-23T11:00:44","modified_gmt":"2015-04-23T11:00:44","slug":"wind-data-logging","status":"publish","type":"post","link":"https:\/\/warmcat.uk\/?p=133","title":{"rendered":"Wind Data Logging"},"content":{"rendered":"<p>A friend of mine wanted to find out which way the wind generally blows in his garden, as he is planning to install a pond and the wind direction would influence where he placed certain equipment.<\/p>\n<p>So\u00a0we decided on\u00a0wind speed and direction sensors, logging the data to SD card over a period of days\/weeks. After some quick research on SD cards, it turns out they are rather easy to interface with Arduino via SPI; the only issue being that SD cards&#8217; logic is 3.3v.<\/p>\n<p>I ordered an SD card breakout board (cheap at\u00a0a few pound) and while waiting for it to arrive, made my own crude version; SD card power supplied from the Arduino&#8217;s 3.3v and resistor pair voltage dividers for the data lines.<\/p>\n<p>The wind speed sensor simply closed it&#8217;s contacts twice per rotation. The direction sensor was a little more complicated, at eight equally spaced positions different resistances were measured across it&#8217;s two connections.<\/p>\n<p>So the plan was to connect the speed sensor to one of the Arduino&#8217;s digital pins (one with interrupt capability) utilising internal pull-up resistor, and the direction sensor to one of the analog pins so that we can effectively convert the resistance to an analog value. Notice the 0.1 microfarad decoupling cap across the speed sensor for de-bounce.<\/p>\n<p>See this schematic I put together.<\/p>\n<p><a href=\"http:\/\/www.fartmagnet.co.uk\/warmcat\/wp-content\/uploads\/2015\/02\/WindSensor6.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-131\" src=\"http:\/\/www.fartmagnet.co.uk\/warmcat\/wp-content\/uploads\/2015\/02\/WindSensor6.png\" alt=\"WindSensor6\" width=\"731\" height=\"656\" srcset=\"https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/WindSensor6.png 731w, https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/WindSensor6-300x269.png 300w, https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/WindSensor6-350x314.png 350w\" sizes=\"auto, (max-width: 731px) 100vw, 731px\" \/><\/a><\/p>\n<p>I used a spare micro-SD card adaptor as a &#8216;socket&#8217; by soldering some header pins to it. While testing, I temporarily hooked up an LCD display to make it a little easier to see what was going on.<\/p>\n<p><a href=\"http:\/\/www.fartmagnet.co.uk\/warmcat\/wp-content\/uploads\/2015\/02\/WindSensor3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-125\" src=\"http:\/\/www.fartmagnet.co.uk\/warmcat\/wp-content\/uploads\/2015\/02\/WindSensor3-300x225.png\" alt=\"WindSensor3\" width=\"300\" height=\"225\" srcset=\"https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/WindSensor3-300x225.png 300w, https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/WindSensor3-350x262.png 350w, https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/WindSensor3.png 1024w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p><a href=\"http:\/\/www.fartmagnet.co.uk\/warmcat\/wp-content\/uploads\/2015\/02\/WindSensor2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-123\" src=\"http:\/\/www.fartmagnet.co.uk\/warmcat\/wp-content\/uploads\/2015\/02\/WindSensor2-225x300.png\" alt=\"WindSensor2\" width=\"225\" height=\"300\" srcset=\"https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/WindSensor2-225x300.png 225w, https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/WindSensor2-350x466.png 350w, https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/WindSensor2.png 768w\" sizes=\"auto, (max-width: 225px) 100vw, 225px\" \/><\/a>\u00a0<a href=\"http:\/\/www.fartmagnet.co.uk\/warmcat\/wp-content\/uploads\/2015\/02\/WindSensor1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-121\" src=\"http:\/\/www.fartmagnet.co.uk\/warmcat\/wp-content\/uploads\/2015\/02\/WindSensor1-225x300.png\" alt=\"WindSensor1\" width=\"225\" height=\"300\" srcset=\"https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/WindSensor1-225x300.png 225w, https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/WindSensor1-350x466.png 350w, https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/WindSensor1.png 768w\" sizes=\"auto, (max-width: 225px) 100vw, 225px\" \/><\/a><\/p>\n<p>How it works:<\/p>\n<p>Upon power-up, a random filename is created ready for data to be recorded into. e.g. XXXX-1.CSV<\/p>\n<p>The wind speed sensor is connected to pin 2 of the Arduino, which can be utilised as an interrupt. Every time the speed sensor makes half a turn, the interrupt function runs.<br \/>\nOn each run, the wind speed counter is incremented, and the position logged.<\/p>\n<p>Once per minute, the average speed over that minute is calculated, along with the most common direction recorded. These values are then written to the current .CSV file on the SD card.<\/p>\n<p>Every 6 hours a new file is created, XXXX-2.CSV then XXXX-3.CSV etc. Each holding 360 entries. We decided to do this in case of data-loss, at least we would only lose 6 hours and not the entire week for example. The reason for the random filename, was incase power was lost and then regained for some reason, we didn&#8217;t want the files to become overwritten (better safe than sorry eh).<\/p>\n<p>Once it was confirmed working, I wrote it to a 5v Arduino mini pro, and connected it all up with the micro SD card board. One option would have been to use a 3.3v Arduino mini pro, negating the use for a proper SD card board and it&#8217;s 3.3v regulated logic level conversion. Anyway, it works and does the job.<\/p>\n<p><a href=\"http:\/\/www.fartmagnet.co.uk\/warmcat\/wp-content\/uploads\/2015\/02\/WindSensor5.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-129\" src=\"http:\/\/www.fartmagnet.co.uk\/warmcat\/wp-content\/uploads\/2015\/02\/WindSensor5-225x300.png\" alt=\"WindSensor5\" width=\"225\" height=\"300\" srcset=\"https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/WindSensor5-225x300.png 225w, https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/WindSensor5-350x466.png 350w, https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/WindSensor5.png 768w\" sizes=\"auto, (max-width: 225px) 100vw, 225px\" \/><\/a>\u00a0<a href=\"http:\/\/www.fartmagnet.co.uk\/warmcat\/wp-content\/uploads\/2015\/02\/WindSensor4.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-127\" src=\"http:\/\/www.fartmagnet.co.uk\/warmcat\/wp-content\/uploads\/2015\/02\/WindSensor4-225x300.png\" alt=\"WindSensor4\" width=\"225\" height=\"300\" srcset=\"https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/WindSensor4-225x300.png 225w, https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/WindSensor4-350x466.png 350w, https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/WindSensor4.png 768w\" sizes=\"auto, (max-width: 225px) 100vw, 225px\" \/><\/a><\/p>\n<p>Here&#8217;s some charts compiled by my friend from the data collected in the first week (click to enlarge):<br \/>\n<a href=\"http:\/\/www.fartmagnet.co.uk\/warmcat\/wp-content\/uploads\/2015\/02\/Wind-charts.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-163\" src=\"http:\/\/www.fartmagnet.co.uk\/warmcat\/wp-content\/uploads\/2015\/02\/Wind-charts-723x1024.png\" alt=\"Wind charts\" width=\"723\" height=\"1024\" srcset=\"https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/Wind-charts-723x1024.png 723w, https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/Wind-charts-212x300.png 212w, https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/Wind-charts-350x495.png 350w, https:\/\/warmcat.uk\/wp-content\/uploads\/2015\/02\/Wind-charts.png 1754w\" sizes=\"auto, (max-width: 723px) 100vw, 723px\" \/><\/a>Here you can download the xlsx file my friend used to create the above charts :\u00a0<a href=\"http:\/\/www.fartmagnet.co.uk\/warmcat\/wp-content\/uploads\/2015\/02\/Wind.xlsx\">Wind.xlsx<\/a><\/p>\n<p>Find the\u00a0code below.<\/p>\n<p>&#8211; Wayne<\/p>\n<p>[pastacode lang=&#8221;c&#8221; message=&#8221;&#8221; highlight=&#8221;&#8221; provider=&#8221;manual&#8221;]<\/p>\n<pre><code>\/\/ ================================================= \/\/\r\n\/\/             WIND SENSOR LOGGER PROGRAM            \/\/\r\n\/\/ ================================================= \/\/\r\n\/\/ Date: 05 Jan 2015                                 \/\/\r\n\/\/ Author: Wayne K Jones \/ www.warmcat.uk            \/\/\r\n\/\/ Free for non-commercial use, however please give  \/\/\r\n\/\/ credit to the author.                             \/\/\r\n\/\/ ================================================= \/\/\r\n\r\n\r\n#include &lt;SD.h&gt;\r\n\r\nint directionPin = A0; \/\/ for wind direction\r\nconst int chipSelect = 10;\r\n\r\nint rpmcount;\r\nint rpm;\r\nunsigned long timeold;\r\nlong randNum;\r\nint moo=0;\r\nint foo=0;\r\nint n = 0;  \/\/1\r\nint ne = 0; \/\/2\r\nint e = 0;  \/\/3\r\nint se = 0; \/\/4\r\nint s = 0;  \/\/5\r\nint sw = 0; \/\/6\r\nint w = 0;  \/\/7\r\nint nw = 0; \/\/8\r\nint mostdir = 0;\r\nint mostdircount = 0;\r\nfloat dir = 0;\r\nFile logFile;\r\nString filenamePrefix = &#34;&#34;;\r\n\r\nvoid setup() {\r\n  Serial.begin(9600);\r\n  \r\n  \/\/Random filename generation \/\/\r\n  randomSeed(analogRead(1)); \/\/use Analog 1 for random seed\r\n  randNum = random(1000,9999);\r\n  filenamePrefix = filenamePrefix + randNum + &#34;-&#34;;\r\n  \/\/ ========================= \/\/\r\n  \r\n  attachInterrupt(0, rpm_int, FALLING); \/\/pin 2\r\n  digitalWrite(2,HIGH);\r\n  rpmcount =0;\r\n  rpm =0;\r\n  timeold =0;\r\n  Serial.print(&#34;Initializing SD card...&#34;);\r\n  \/\/ make sure that the default chip select pin is set to output, even if you don&#039;t use it:\r\n  pinMode(10, OUTPUT);\r\n  \/\/ see if the card is present and can be initialized:\r\n  if (!SD.begin(chipSelect)) {\r\n    Serial.println(&#34;Card failed, or not present&#34;);\r\n    \/\/ don&#039;t do anything more:\r\n    return;\r\n  }\r\n  Serial.println(&#34;card initialized.&#34;);\r\n}\r\n\r\nvoid loop() {\r\n  if (millis() - timeold == 60000) {  \/\/update every minute\r\n    detachInterrupt(0); \/\/pause interrupts\r\n    rpm = rpmcount * 0.5;\r\n    \/\/reset time and rpm count\r\n    timeold = millis();\r\n    rpmcount = 0;\r\n    mostdir = 0; \/\/zero most used direction\r\n    mostdircount = 0; \/\/and the count of said direction\r\n    \/\/ work out which direction variable has largest value\r\n    if (mostdircount &lt; n)  { mostdir = 1; mostdircount = n; }\r\n    if (mostdircount &lt; ne) { mostdir = 2; mostdircount = ne; }\r\n    if (mostdircount &lt; e)  { mostdir = 3; mostdircount = e; }\r\n    if (mostdircount &lt; se) { mostdir = 4; mostdircount = se; }\r\n    if (mostdircount &lt; s)  { mostdir = 5; mostdircount = s; }\r\n    if (mostdircount &lt; sw) { mostdir = 6; mostdircount = sw; }\r\n    if (mostdircount &lt; w)  { mostdir = 7; mostdircount = w; }\r\n    if (mostdircount &lt; nw) { mostdir = 8; mostdircount = nw; }\r\n\r\n    String data = &#34;&#34;; \/\/initialise data string\r\n    switch (mostdir) {\r\n    case 0:\r\n      data = data + &#34;-&#34;; \/\/no wind\r\n      break;\r\n    case 1:\r\n      data = data + &#34;N&#34;; \/\/add N wind dir to data string\r\n      break;\r\n    case 2:\r\n      data = data + &#34;NE&#34;;\r\n      break;\r\n    case 3:\r\n      data = data + &#34;E&#34;;\r\n      break;\r\n    case 4:\r\n      data = data + &#34;SE&#34;;\r\n      break;\r\n    case 5:\r\n      data = data + &#34;S&#34;;\r\n      break;\r\n    case 6:\r\n      data = data + &#34;SW&#34;;\r\n      break;\r\n    case 7:\r\n      data = data + &#34;W&#34;;\r\n      break;\r\n    case 8:\r\n      data = data + &#34;NW&#34;;\r\n      break;\r\n    }\r\n    data = data + &#34;,&#34; + rpm; \/\/add rpm to data string\r\n    Serial.println(data);\r\n    \r\n    if (moo % 360 == 0) {\r\n      \/\/every 360 moos (every 6 hours) increment foo (which creates a new file)\r\n      foo++;\r\n    }\r\n    moo++; \/\/moo increments every time this if statement runs\r\n    String filename = &#34;&#34;; \/\/initialse filename string\r\n    filename = filenamePrefix + foo + &#34;.csv &#34;; \/\/create filename from random number, foo, and extension\r\n    \/\/ so we get XXXX-Y.csv ... XXXX being the randomly created number every time arduino power cycled.\r\n    \/\/ Y being &#039;foo&#039; which increments every hour\r\n    \/\/convert filename string to char array\r\n    char filenameCharArray[filename.length()];\r\n    filename.toCharArray(filenameCharArray, filename.length());\r\n    logFile = SD.open(filenameCharArray, FILE_WRITE); \/\/create or open file\r\n    if (logFile) {\r\n      \/\/ if the file opened okay, write to it:\r\n      Serial.print(&#34;Writing to &#34;);\r\n      Serial.println(filenameCharArray);\r\n      logFile.println(data);\r\n      \/\/ close the file:\r\n      logFile.close();\r\n      Serial.println(&#34;done.&#34;);\r\n    } else {\r\n      \/\/ if the file didn&#039;t open, print an error:\r\n      Serial.print(&#34;error opening &#34;);\r\n      Serial.println(filenameCharArray);\r\n    }\r\n    \/\/Clear counts for next time\r\n    n = 0;  \/\/1\r\n    ne = 0; \/\/2\r\n    e = 0;  \/\/3\r\n    se = 0; \/\/4\r\n    s = 0;  \/\/5\r\n    sw = 0; \/\/6\r\n    w = 0;  \/\/7\r\n    nw = 0; \/\/8\r\n    attachInterrupt(0, rpm_int, FALLING);\r\n  }\r\n\r\n}\r\nvoid rpm_int() {  \/\/our interrupt every time wind sensor 1\/2 turn\r\n  rpmcount++;\r\n  dir = analogRead(directionPin); \/\/increment variable of current direction\r\n  if ((dir &gt; 61) &amp;&amp; (dir &lt; 93)) n++;\r\n  if ((dir &gt; 123) &amp;&amp; (dir &lt; 195)) ne++;\r\n  if ((dir &gt; 240) &amp;&amp; (dir &lt; 290)) e++;\r\n  if ((dir &gt; 596) &amp;&amp; (dir &lt; 632)) se++;\r\n  if ((dir &gt; 930) &amp;&amp; (dir &lt; 950)) s++;\r\n  if ((dir &gt; 820) &amp;&amp; (dir &lt; 891)) sw++;\r\n  if ((dir &gt; 700) &amp;&amp; (dir &lt; 790)) w++;\r\n  if ((dir &gt; 400) &amp;&amp; (dir &lt; 470)) nw++;\r\n}\r\n<\/code><\/pre>\n<p>[\/pastacode]<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p class=\"excerpt\">A friend of mine wanted to find out which way the wind generally blows in his garden, as he is planning to install a pond and the wind direction would&hellip; <span class=\"more-link\">more<\/span><\/p>\n","protected":false},"author":3,"featured_media":153,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[39],"tags":[41,63,43,65,67,9,61],"class_list":["post-133","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-electronics","tag-arduino","tag-data","tag-electronics-2","tag-logging","tag-sd","tag-sensor","tag-wind"],"_links":{"self":[{"href":"https:\/\/warmcat.uk\/index.php?rest_route=\/wp\/v2\/posts\/133","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/warmcat.uk\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/warmcat.uk\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/warmcat.uk\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/warmcat.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=133"}],"version-history":[{"count":14,"href":"https:\/\/warmcat.uk\/index.php?rest_route=\/wp\/v2\/posts\/133\/revisions"}],"predecessor-version":[{"id":173,"href":"https:\/\/warmcat.uk\/index.php?rest_route=\/wp\/v2\/posts\/133\/revisions\/173"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/warmcat.uk\/index.php?rest_route=\/wp\/v2\/media\/153"}],"wp:attachment":[{"href":"https:\/\/warmcat.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=133"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/warmcat.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=133"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/warmcat.uk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=133"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}