├── README.md ├── cover.jpg ├── experiment10a.js ├── experiment10b.js ├── experiment10c.js ├── experiment11.js ├── experiment12.js ├── experiment13.js ├── experiment14a.js ├── experiment14b.js ├── experiment14c.js ├── experiment14d.js ├── experiment15.js ├── experiment16.js ├── experiment19a.html ├── experiment19b.html ├── experiment20.html ├── experiment21.html ├── experiment22.html ├── experiment25.js ├── experiment26.html ├── experiment28.js ├── experiment29.js ├── experiment30.js ├── experiment31.js ├── experiment32.js ├── experiment34.html ├── experiment34.js ├── experiment35.js ├── experiment36.html ├── experiment38a.js ├── experiment38b.js ├── experiment38c.html ├── experiment38d.html ├── experiment38e.js ├── experiment39.html ├── experiment39a.js ├── experiment39b.js ├── experiment4a.js ├── experiment4b.js ├── experiment5.js ├── experiment6.js ├── experiment7.js ├── experiment8.js ├── experiment9a.js ├── experiment9b.js ├── experiment9c.js └── experiment9d.js /README.md: -------------------------------------------------------------------------------- 1 | # Making Things Smart 2 | 3 | [!['Making Things Smart' book](cover.jpg)](http://shop.oreilly.com/product/0636920031246.do) 4 | 5 | Extra information for the ['Making Things Smart' book by Gordon Williams](http://shop.oreilly.com/product/0636920031246.do) (available from [O'Reilly](http://shop.oreilly.com/product/0636920031246.do) and [Amazon](https://www.amazon.com/gp/product/1680451898/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1680451898&linkCode=as2&tag=espruino-20&linkId=9a3b6e7c3a4f24c8f894e6a039828502)) 6 | 7 | This code is designed for [Espruino JavaScript Microcontroller boards](http://www.espruino.com/Order) 8 | 9 | ## Code Examples 10 | 11 | ### Chapter 1 - Introduction 12 | 13 | An introduction to the book. 14 | 15 | ### Chapter 2 - What is a Microcontroller? 16 | 17 | How is a microcontroller different to a normal PC? What is an ARM, some history of microcontrollers, and how is it different to 8 bit AVR microcontrollers used in many Arduino boards? 18 | 19 | ### Chapter 3 - Getting Started with Espruino 20 | 21 | How to get your Espruino board up and running and issue your first commands. 22 | 23 | ### Chapter 4 - Getting Started with JavaScript 24 | 25 | An introduction to JavaScript for readers with experience of other languages. 26 | 27 | ### Chapter 5 - Motors 28 | 29 | Making motors, and controlling stepper motors. 30 | 31 | * [Experiment 4 Part 1](experiment4a.js) 32 | * [Experiment 4 Part 2](experiment4b.js) 33 | * [Experiment 5](experiment5.js) 34 | 35 | ### Chapter 6 - Stroboscopes 36 | 37 | Connecting a PC fan to an Espruino, and lighting the fan at exactly the same point at every revolution. 38 | 39 | * [Experiment 6](experiment6.js) 40 | * [Experiment 7](experiment7.js) 41 | * [Experiment 8](experiment8.js) 42 | 43 | ### Chapter 7 - John Logie Baird's TV 44 | 45 | Using the PC fan with more markers to create a low-resolution TV. 46 | 47 | * [Experiment 9 Part 1](experiment9a.js) 48 | * [Experiment 9 Part 2](experiment9b.js) 49 | * [Experiment 9 Part 3](experiment9c.js) 50 | * [Experiment 9 Part 4](experiment9d.js) 51 | * [Experiment 10 Part 1](experiment10a.js) 52 | * [Experiment 10 Part 2](experiment10b.js) 53 | 54 | ### Chapter 8 - Making a Simple Robot 55 | 56 | Make a robot using two continuous-rotation servo motors and a piece of breadboard. 57 | 58 | * [Experiment 11](experiment11.js) 59 | * [Experiment 12](experiment12.js) 60 | * [Experiment 13](experiment13.js) 61 | 62 | ### Chapter 9 - Pen Plotter 63 | 64 | Using two servo motors, create a simple pen plotter. 65 | 66 | * [Experiment 14 Part 1](experiment14a.js) 67 | * [Experiment 14 Part 2](experiment14b.js) 68 | * [Experiment 14 Part 3](experiment14c.js) 69 | * [Experiment 14 Part 4](experiment14d.js) 70 | 71 | ### Chapter 10 - Digital Pinhole Camera 72 | 73 | With two servo motors and a light sensor, create a low-resolution camera. 74 | 75 | * [Experiment 15](experiment15.js) 76 | 77 | ### Chapter 11 - Printer 78 | 79 | Create a printer with a cardboard tube, threaded bar, and servo motors. 80 | 81 | * [Experiment 16](experiment16.js) 82 | 83 | 84 | ### Chapter 12 - Wired Communication 85 | 86 | The oscilloscope used in this chapter is available from: 87 | 88 | * Try it out: https://espruino.github.io/webaudio-oscilloscope/ 89 | * Source code: https://github.com/espruino/webaudio-oscilloscope 90 | 91 | ### Chapter 13 - Cutting the Cord: Infrared 92 | 93 | Using a web page and some simple hardware to decode infrared remote control signals with the headphone jack and control [Dweet](http://dweet.io/) and [IFTTT](https://ifttt.com/). 94 | 95 | * [Experiment 19 Part 1](experiment19a.html) 96 | * [Experiment 19 Part 2](experiment19b.html) 97 | * [Experiment 20](experiment20.html) 98 | * [Experiment 21](experiment21.html) 99 | * [Experiment 22](experiment22.html) 100 | 101 | ### Chapter 14 - Cutting the Cord: Radio Signals 102 | 103 | Using a 315Mhz/433Mhz receiver - also conected to the headphone jack - to decode radio signals, and then sending radio signals from an Espruino board. 104 | 105 | * [Experiment 25](experiment25.js) 106 | * [Experiment 26](experiment26.html) 107 | 108 | ### Chapter 15 - Cutting the Cord: WiFi 109 | 110 | Adding ESP8266 WiFi to an Espruino Pico, sending and getting data from the internet, and creating a web server to control things. 111 | 112 | * [Experiment 28](experiment28.js) 113 | * [Experiment 29](experiment29.js) 114 | * [Experiment 30](experiment30.js) 115 | * [Experiment 31](experiment31.js) 116 | * [Experiment 32](experiment32.js) 117 | 118 | ### Chapter 16 - Bluetooth Low Energy 119 | 120 | Using [Puck.js](http://www.puck-js.com/) to count the number of times a door has opened and transmit it over Bluetooth Low Energy. 121 | 122 | * [Experiment 34 Espruino JavaScript](experiment34.js) 123 | * [Experiment 34 HTML](experiment34.html) 124 | * [Experiment 35](experiment35.js) 125 | * [Experiment 36 Espruino JavaScript](experiment36.js) 126 | * [Experiment 36 HTML](experiment36.html) 127 | 128 | **Note:** Google has shut down some features that were used for Experiment 35: 129 | 130 | * [Eddystone notifications are now disabled](https://android-developers.googleblog.com/2018/10/discontinuing-support-for-android.html) 131 | because of abuse by advertisers, so Eddystone devices will no longer appear as Android Notifications. 132 | * The [goo.gl URL shortener is shutting down](https://developers.googleblog.com/2018/03/transitioning-google-url-shortener.html) 133 | so you'll need to use something like [bit.ly](https://bitly.com/) instead. 134 | 135 | ### Chapter 17 - XY Plotter 136 | 137 | Building a pen plotter with stepper motors so get much more accurate positioning. 138 | 139 | * [Experiment 38 Part 1](experiment38a.js) 140 | * [Experiment 38 Part 2](experiment38b.js) 141 | * [Experiment 38 Part 3 HTML](experiment38c.html) 142 | * [Experiment 38 Part 4 HTML](experiment38d.html) 143 | * [Experiment 38 Part 5](experiment38e.js) 144 | 145 | ### Chapter 18 - Internet-connected Plotter 146 | 147 | Connecting the pen plotter from Chapter 17 to the internet. 148 | 149 | * [Experiment 39 HTML Test page](experiment39.html) 150 | * [Experiment 39 Part 1](experiment39a.js) 151 | * [Experiment 39 Part 2](experiment39b.js) 152 | 153 | ### Chapter 19 - So what now? 154 | 155 | Ideas about what to do next. 156 | 157 | ### Appendix A - Parts and Materials 158 | 159 | Where to find/buy the materials used in this book. 160 | 161 | ### Appendix B - Common Espruino Commands and Variables 162 | 163 | A description of common Espruino JavaScript commands. 164 | 165 | ### Appendix C - Espruino Assembler 166 | 167 | Writing ARM Thumb assembly code with Espruino 168 | 169 | 170 | ## Purchasing Information 171 | 172 | Where to find some of the component parts used in the book. 173 | 174 | ... to come soon. 175 | -------------------------------------------------------------------------------- /cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espruino/making-things-smart/e9ce3a6845c66f53af7f59449d05f881a9b8378d/cover.jpg -------------------------------------------------------------------------------- /experiment10a.js: -------------------------------------------------------------------------------- 1 | var SENSE = A8; 2 | var LIGHT = B6; 3 | var counter = 0; 4 | 5 | var blades = 7; 6 | var t = 1000 / blades; 7 | var pulses = [5]; 8 | for (var i=0;i 1) pos = 0; 25 | // Work out an angle between 0 and 360 degrees, but in Radians 26 | var angle = pos * Math.PI * 2; 27 | // Now use sin and cos to move the servos in a circular motion 28 | motors[0] = Math.sin(angle)*size; 29 | motors[1] = Math.cos(angle)*size; 30 | } 31 | 32 | setInterval(updateServos, 20); 33 | -------------------------------------------------------------------------------- /experiment14b.js: -------------------------------------------------------------------------------- 1 | // Draws a diamond 2 | var PEN_DOWN = PEN_DOWN_VALUE_HERE; // motors[2] when pen touches paper 3 | var PEN_UP = PEN_UP_VALUE_HERE; // motors[2] when pen is away from paper 4 | var OFFSET_LEFT = 0.1; // offset to make left servo horizontal 5 | var OFFSET_RIGHT = -0.1; // offset to make right servo horizontal 6 | 7 | var motors = [0,0,PEN_UP]; 8 | 9 | function updateServos() { 10 | getNewPosition(); 11 | digitalPulse(B3, 1, E.clip(1.5+(motors[0]+OFFSET_LEFT), 1, 2)); 12 | digitalPulse(B3, 1, 0); // wait for pulse 13 | digitalPulse(B4, 1, E.clip(1.5-(motors[1]+OFFSET_RIGHT), 1, 2)); 14 | digitalPulse(B4, 1, 0); // wait for pulse 15 | digitalPulse(B5, 1, E.clip(1.5+motors[2], 1, 2)); // Pen 16 | } 17 | 18 | var pos = 0; 19 | var size = 0.1; 20 | 21 | function getNewPosition() { 22 | // increment pos slowly between 0 and 1 23 | pos += 0.002; 24 | if (pos > 1) pos = 0; 25 | // Multiply by 4, for each edge of the square 26 | var sq = pos*4; 27 | // Now set the position for each edge: 28 | if (sq<1) { // top edge 29 | motors[0] = (sq-0.5)*2*size; 30 | motors[1] = -size; 31 | } else if (sq<2) { // right edge 32 | motors[0] = size; 33 | motors[1] = (sq-1.5)*2*size; 34 | } else if (sq<3) { // bottom edge 35 | motors[0] = (2.5-sq)*2*size; 36 | motors[1] = size; 37 | } else { // left edge 38 | motors[0] = -size; 39 | motors[1] = (3.5-sq)*2*size; 40 | } 41 | } 42 | 43 | setInterval(updateServos, 20); 44 | -------------------------------------------------------------------------------- /experiment14c.js: -------------------------------------------------------------------------------- 1 | // Draws a square 2 | var PEN_DOWN = PEN_DOWN_VALUE_HERE; // motors[2] when pen touches paper 3 | var PEN_UP = PEN_UP_VALUE_HERE; // motors[2] when pen is away from paper 4 | var OFFSET_LEFT = 0.1; // offset to make left servo horizontal 5 | var OFFSET_RIGHT = -0.1; // offset to make right servo horizontal 6 | 7 | var motors = [0,0,PEN_UP]; 8 | 9 | function updateServos() { 10 | getNewPosition(); 11 | var x = motors[0]; 12 | var y = motors[1]; 13 | y = y * 3.5 / 6; 14 | var l = y + x; 15 | var r = y - x; 16 | digitalPulse(B3, 1, E.clip(1.5+(l+OFFSET_LEFT), 1, 2)); // Left 17 | digitalPulse(B3, 1, 0); // wait for pulse 18 | digitalPulse(B4, 1, E.clip(1.5-(r+OFFSET_RIGHT), 1, 2)); // Right 19 | digitalPulse(B4, 1, 0); // wait for pulse 20 | digitalPulse(B5, 1, E.clip(1.5+motors[2], 1, 2)); // Pen 21 | } 22 | 23 | var pos = 0; 24 | var size = 0.1; 25 | 26 | function getNewPosition() { 27 | // increment pos slowly between 0 and 1 28 | pos += 0.002; 29 | if (pos > 1) pos = 0; 30 | // Multiply by 4, for each edge of the square 31 | var sq = pos*4; 32 | // Now set the position for each edge: 33 | if (sq<1) { // top edge 34 | motors[0] = (sq-0.5)*2*size; 35 | motors[1] = -size; 36 | } else if (sq<2) { // right edge 37 | motors[0] = size; 38 | motors[1] = (sq-1.5)*2*size; 39 | } else if (sq<3) { // bottom edge 40 | motors[0] = (2.5-sq)*2*size; 41 | motors[1] = size; 42 | } else { // left edge 43 | motors[0] = -size; 44 | motors[1] = (3.5-sq)*2*size; 45 | } 46 | } 47 | 48 | setInterval(updateServos, 20); 49 | -------------------------------------------------------------------------------- /experiment14d.js: -------------------------------------------------------------------------------- 1 | // Draws a square, but using a function call and callbacks 2 | var PEN_DOWN = PEN_DOWN_VALUE_HERE; // motors[2] when pen touches paper 3 | var PEN_UP = PEN_UP_VALUE_HERE; // motors[2] when pen is away from paper 4 | var OFFSET_LEFT = 0.1; // offset to make left servo horizontal 5 | var OFFSET_RIGHT = -0.1; // offset to make right servo horizontal 6 | 7 | var motors = [0,0,PEN_UP]; 8 | 9 | function updateServos() { 10 | getNewPosition(); 11 | var x = motors[0]; 12 | var y = motors[1]; 13 | y = y * 3.5 / 6; 14 | var l = y + x; 15 | var r = y - x; 16 | digitalPulse(B3, 1, E.clip(1.5+(l+OFFSET_LEFT), 1, 2)); // Left 17 | digitalPulse(B3, 1, 0); // wait for pulse 18 | digitalPulse(B4, 1, E.clip(1.5-(r+OFFSET_RIGHT), 1, 2)); // Right 19 | digitalPulse(B4, 1, 0); // wait for pulse 20 | digitalPulse(B5, 1, E.clip(1.5+motors[2], 1, 2)); // Pen 21 | } 22 | 23 | function doNothing() { 24 | // do nothing 25 | } 26 | 27 | var getNewPosition = doNothing; 28 | 29 | function move(x, y, callback) { 30 | // First, get the old positions 31 | var oldx = motors[0]; 32 | var oldy = motors[1]; 33 | // Now work out the distance using pythagoras 34 | var dx = oldx-x; 35 | var dy = oldy-y; 36 | var d = Math.sqrt(dx*dx + dy*dy); 37 | // Make sure we move at the right speed, not 38 | // too fast or slow! 39 | var speed = 0.002/d; 40 | // and now have 'pos', our position in the line 41 | var pos = 0; 42 | // finally, set the getNewPosition function to something 43 | // that will darw a line 44 | 45 | getNewPosition = function() { 46 | pos += speed; 47 | if (pos>1) { 48 | // If we've finished, stop and 49 | // call the callback 50 | pos = 1; 51 | getNewPosition = doNothing; 52 | if (callback) callback(); 53 | } 54 | // Set the motor positions up by interpolating 55 | // between oldx and x, oldy and y 56 | motors[0] = oldx*(1-pos) + x*pos; 57 | motors[1] = oldy*(1-pos) + y*pos; 58 | }; 59 | } 60 | 61 | setInterval(updateServos, 20); 62 | 63 | 64 | function penDown(yes) { 65 | if (yes) motors[2] = PEN_DOWN; 66 | else motors[2] = PEN_UP; 67 | } 68 | 69 | function square(x,y,size, callback) { 70 | move(x-size, y-size, function() { 71 | penDown(true); 72 | move(x+size, y-size, function() { 73 | move(x+size, y+size, function() { 74 | move(x-size, y+size, function() { 75 | move(x-size, y-size, function() { 76 | penDown(false); 77 | if (callback) callback(); 78 | }); 79 | }); 80 | }); 81 | }); 82 | }); 83 | } 84 | 85 | // now type square(0, 0, 0.1) 86 | -------------------------------------------------------------------------------- /experiment15.js: -------------------------------------------------------------------------------- 1 | // how detailed our picture will be 2 | var WIDTH = 48; 3 | var HEIGHT = 48; 4 | var PIXELS = WIDTH*HEIGHT; 5 | 6 | // The position in our scan 7 | var px=0, py=0; 8 | 9 | // Our pixel data 10 | var data = new Float32Array(PIXELS); 11 | 12 | function readPixel() { 13 | var light = analogRead(A5); 14 | // work out where in the array it should go 15 | var idx = px + (py*WIDTH); 16 | // save the data away 17 | data[idx] = light; 18 | } 19 | 20 | function updateServos() { 21 | readPixel(); 22 | 23 | /* Bring px and py into the 24 | right range for the servo motors */ 25 | var x = ((px/WIDTH) - 0.5) / 3; 26 | var y = ((py/HEIGHT) - 0.5) / 3; 27 | 28 | // And move the servos 29 | digitalPulse(B3, 1, E.clip(1.5+x, 1, 2)); 30 | digitalPulse(B3, 1, 0); 31 | digitalPulse(B4, 1, E.clip(1.5+y, 1, 2)); 32 | 33 | /* Move to the next position. Go right */ 34 | px++; 35 | // or if we're at the end of the line, 36 | // go back to the start 37 | if (px>=WIDTH) { 38 | px=0; 39 | py++; 40 | } 41 | if (py>=HEIGHT) { 42 | /* If we got to the end, don't do anything 43 | else. stop calling updateServos */ 44 | clearInterval(scanInterval); 45 | } 46 | } 47 | 48 | var scanInterval = setInterval(updateServos, 20); 49 | 50 | // Draw our pixels out to the screen 51 | function draw() { 52 | /* We have to use characters to represent 53 | each shade of color, so we're putting some 54 | characters in a string that get progressively 55 | more 'dense' */ 56 | var shades = " .:;*@#"; 57 | /* Work out the maximum and minimum 58 | values, so we can scale the image 59 | brightness properly */ 60 | var min = data[0]; 61 | var max = data[0]; 62 | data.forEach(function(pixel) { 63 | if (pixel < min) min = pixel; 64 | if (pixel > max) max = pixel; 65 | }); 66 | // Now we can print the data out, line by line 67 | var n = 0; 68 | for (var y=0;y max) max = pixel; 86 | }); 87 | // Print the data out, line by line 88 | var n = 0; 89 | for (var y=0;y lightAverage-0.03) { 62 | // If it jumps back up, we've passed it 63 | hasFoundMarker = false; 64 | } 65 | // update the average 66 | lightAverage = lightAverage*0.99 + light*0.01; 67 | } 68 | 69 | setInterval(lightChecker, 10); 70 | 71 | var g = Graphics.createArrayBuffer(96,48,1); 72 | g.setFontVector(48); 73 | g.drawString("=P",0,0); 74 | 75 | function draw() { 76 | for (var y=0;y 2 | 3 | Making Things Smart Experiment 19 4 | 5 | 6 |

 7 |     
89 |   
90 | 
91 | 


--------------------------------------------------------------------------------
/experiment19b.html:
--------------------------------------------------------------------------------
  1 | 
  2 |   
  3 |     Making Things Smart Experiment 19
  4 |   
  5 |   
  6 |     

  7 |     
110 |   
111 | 
112 | 


--------------------------------------------------------------------------------
/experiment20.html:
--------------------------------------------------------------------------------
  1 | 
  2 |   
  3 |     Making Things Smart Experiment 20
  4 |   
  5 |   
  6 |     
7 |

  8 |     
119 |   
120 | 
121 | 


--------------------------------------------------------------------------------
/experiment21.html:
--------------------------------------------------------------------------------
  1 | 
  2 |   
  3 |     Making Things Smart Experiment 21
  4 |   
  5 |   
  6 |     

You should see http://dweet.io/follow/espruino updating with 7 | any remote control signals received.

8 |

  9 |     
127 |   
128 | 
129 | 


--------------------------------------------------------------------------------
/experiment22.html:
--------------------------------------------------------------------------------
  1 | 
  2 |   
  3 |     Making Things Smart Experiment 22
  4 |   
  5 |   
  6 |     

Remember to update xxx_MY_KEY_HERE_xxx with your key from IFTTT!

7 |

  8 |     
128 |   
129 | 
130 | 


--------------------------------------------------------------------------------
/experiment25.js:
--------------------------------------------------------------------------------
 1 | function transmit(txt) {
 2 |   // Ensure we're dealing with a string
 3 |   txt = txt.toString();
 4 |   // Work out what to send
 5 |   // Initial 5ms pulse
 6 |   var d = [5];
 7 |   // data for each character
 8 |   for (var i=0;i
  2 |   
  3 |     Making Things Smart Experiment 26
  4 |   
  5 |   
  6 |     

  7 |     
149 |   
150 | 
151 | 


--------------------------------------------------------------------------------
/experiment28.js:
--------------------------------------------------------------------------------
1 | var l="";
2 | Serial1.on('data', function(d) {l+=d;});
3 | Serial1.setup(115200, { tx: B6, rx : B7 });
4 | Serial1.write("AT+GMR\r\n");
5 | setTimeout(function(){console.log(l);},1000);
6 | 


--------------------------------------------------------------------------------
/experiment29.js:
--------------------------------------------------------------------------------
 1 | var WIFI_NAME = "";
 2 | var WIFI_KEY = "";
 3 | 
 4 | function onConnected() {
 5 |   console.log("Connected");
 6 | }
 7 | 
 8 | // This code is for Espruino Pico + ESP8266
 9 | Serial1.setup(115200, { tx: B6, rx : B7 });
10 | var wifi = require("ESP8266WiFi_0v25").connect(Serial1, function(err) {
11 |   if (err) throw err;
12 |   console.log("Connecting to WiFi");
13 |   wifi.connect(WIFI_NAME, WIFI_KEY, function(err) {
14 |     if (err) {
15 |       console.log("Connection error: "+err);
16 |       return;
17 |     }
18 |     onConnected();
19 |   });
20 | });
21 | 
22 | /*
23 | // For Espruino WiFi, use the following code
24 | var wifi = require("EspruinoWiFi");
25 | console.log("Connecting to WiFi");
26 | wifi.connect(WIFI_NAME, { password : WIFI_KEY }, function(err) {
27 |   if (err) {
28 |     console.log("Connection error: "+err);
29 |     return;
30 |   }
31 |   onConnected();
32 | });
33 | */
34 | 
35 | /* Now enter the following to get a webpage and print it:
36 | 
37 | require("http").get("http://www.pur3.co.uk/hello.txt", function(res) {
38 |   res.on('data', print);
39 | });
40 | 
41 | */
42 | 


--------------------------------------------------------------------------------
/experiment30.js:
--------------------------------------------------------------------------------
 1 | var WIFI_NAME = "";
 2 | var WIFI_KEY = "";
 3 | var wifi;
 4 | 
 5 | // This code is for Espruino Pico + ESP8266
 6 | function onInit() {
 7 |   USB.setConsole(true);
 8 |   Serial1.setup(115200, { tx: B6, rx : B7 });
 9 |   wifi = require("ESP8266WiFi_0v25").connect(Serial1, function(err) {
10 |     if (err) throw err;
11 |     console.log("Connecting to WiFi");
12 |     wifi.connect(WIFI_NAME, WIFI_KEY, function(err) {
13 |       if (err) throw err;
14 |       onConnected();
15 |     });
16 |   });
17 | }
18 | /*
19 | // For Espruino WiFi, use the following code
20 | function onInit() {
21 |   wifi = require("EspruinoWiFi");
22 |   console.log("Connecting to WiFi");
23 |   wifi.connect(WIFI_NAME, { password : WIFI_KEY }, function(err) {
24 |     if (err) {
25 |       console.log("Connection error: "+err);
26 |       return;
27 |     }
28 |     onConnected();
29 |   });
30 | }
31 | */
32 | 
33 | 
34 | function onConnected() {
35 |   console.log("Connected");
36 |   setInterval(sendDweet, 10000);
37 | }
38 | 
39 | 
40 | function sendDweet() {
41 |   var str = E.getTemperature().toFixed(2);
42 |   console.log("Sending "+str);
43 |   var url = "http://dweet.io/dweet/for/espruino_tmp?temp="+str;
44 |   require("http").get(url, function(res) { });
45 | }
46 | 


--------------------------------------------------------------------------------
/experiment31.js:
--------------------------------------------------------------------------------
 1 | var WIFI_NAME = "";
 2 | var WIFI_KEY = "";
 3 | var wifi;
 4 | 
 5 | // This code is for Espruino Pico + ESP8266
 6 | function onInit() {
 7 |   USB.setConsole(true);
 8 |   Serial1.setup(115200, { tx: B6, rx : B7 });
 9 |   wifi = require("ESP8266WiFi_0v25").connect(Serial1, function(err) {
10 |     if (err) throw err;
11 |     console.log("Connecting to WiFi");
12 |     wifi.connect(WIFI_NAME, WIFI_KEY, function(err) {
13 |       if (err) throw err;
14 |       onConnected();
15 |     });
16 |   });
17 | }
18 | /*
19 | // For Espruino WiFi, use the following code
20 | function onInit() {
21 |   wifi = require("EspruinoWiFi");
22 |   console.log("Connecting to WiFi");
23 |   wifi.connect(WIFI_NAME, { password : WIFI_KEY }, function(err) {
24 |     if (err) {
25 |       console.log("Connection error: "+err);
26 |       return;
27 |     }
28 |     onConnected();
29 |   });
30 | }
31 | */
32 | 
33 | 
34 | function onConnected() {
35 |   console.log("Connected");
36 |   setInterval(getDweet, 10000);
37 | }
38 | 
39 | function onDweetData(data) {
40 |   try {
41 |     json = JSON.parse(data);
42 |     console.log("DWEET> ", json);
43 |     var d = json.with[0].content.on;
44 |     digitalWrite([LED2,LED1], d);
45 |   } catch (e) {
46 |     console.log(e.toString());
47 |   }
48 | }
49 | 
50 | function getDweet() {
51 |   var url = "http://dweet.io/get/latest/dweet/for/espruino_led";
52 |   require("http").get(url, function(res) {
53 |     var data = "";
54 |     res.on('data', function(d) { data+=d; });
55 |     res.on('close', function() {
56 |       onDweetData(data);
57 |     });
58 |   });
59 | }
60 | 


--------------------------------------------------------------------------------
/experiment32.js:
--------------------------------------------------------------------------------
 1 | var WIFI_NAME = "";
 2 | var WIFI_KEY = "";
 3 | var wifi;
 4 | 
 5 | // This code is for Espruino Pico + ESP8266
 6 | function onInit() {
 7 |   USB.setConsole(true);
 8 |   Serial1.setup(115200, { tx: B6, rx : B7 });
 9 |   wifi = require("ESP8266WiFi_0v25").connect(Serial1, function(err) {
10 |     if (err) throw err;
11 |     console.log("Connecting to WiFi");
12 |     wifi.connect(WIFI_NAME, WIFI_KEY, function(err) {
13 |       if (err) throw err;
14 |       onConnected();
15 |     });
16 |   });
17 | }
18 | /*
19 | // For Espruino WiFi, use the following code
20 | function onInit() {
21 |   wifi = require("EspruinoWiFi");
22 |   console.log("Connecting to WiFi");
23 |   wifi.connect(WIFI_NAME, { password : WIFI_KEY }, function(err) {
24 |     if (err) {
25 |       console.log("Connection error: "+err);
26 |       return;
27 |     }
28 |     onConnected();
29 |   });
30 | }
31 | */
32 | 
33 | 
34 | function onConnected() {
35 |   console.log("Connected");
36 |   require("http").createServer(onPageRequest).listen(80);
37 |   wifi.getIP(function(err,ip) {
38 |     console.log("Your IP address is http://"+ip);
39 |   });
40 | }
41 | 
42 | var homePage = ''+
43 |  '

My Espruino

'+ 44 | 'Temperature
'+ 45 | '
'+ 46 | '
'+ 47 | '
'+ 48 | '
'+ 49 | ''; 50 | 51 | function onPageRequest(req, res) { 52 | console.log("Serving "+req.url, req); 53 | var r = url.parse(req.url, true); 54 | if (r.pathname == "/") { 55 | // if an argument is given, set the LED state 56 | if (req.method=="POST" && r.query && r.query.led) 57 | digitalWrite(LED1, r.query.led); 58 | // serve up the page 59 | res.writeHead(200, {"Content-Type": "text/html"}); 60 | res.end(homePage); 61 | } else if (r.pathname == "/getTemp") { 62 | res.writeHead(200, {"Content-Type": "text/html"}); 63 | res.end(''+ 64 | ''+ 65 | ''+E.getTemperature().toFixed(2)+ 66 | ''); 67 | } else { 68 | res.writeHead(404); 69 | res.end("404 - Not Found!"); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /experiment34.html: -------------------------------------------------------------------------------- 1 | 2 | Door Opening reader 3 | 4 | 5 |

6 | Door opened
7 | ?
8 | times... 9 |

10 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /experiment34.js: -------------------------------------------------------------------------------- 1 | // magnetism measured when nothing around 2 | var zeroMag = Puck.mag(); 3 | var wasDoorOpen = false; 4 | var doorOpenings = 0; 5 | 6 | function doorOpened() { 7 | doorOpenings++; 8 | } 9 | 10 | // Called when new magnetic field information is found 11 | function onMag(xyz) { 12 | // work out the distance from zero 13 | var x = xyz.x - zeroMag.x; 14 | var y = xyz.y - zeroMag.y; 15 | var z = xyz.z - zeroMag.z; 16 | // Work out the magnitude of the field 17 | var d = Math.sqrt(x*x + y*y + z*z); 18 | // check door open state 19 | var isDoorOpen = d<500; 20 | if (isDoorOpen != wasDoorOpen) { 21 | if (isDoorOpen) { 22 | doorOpened(); 23 | // flash green LED for open 24 | digitalPulse(LED2,1,100); 25 | } else { 26 | // flash red LED for close 27 | digitalPulse(LED1,1,100); 28 | } 29 | wasDoorOpen = isDoorOpen; 30 | } 31 | } 32 | 33 | // Set callback when magnetic field info is found 34 | Puck.on('mag', onMag); 35 | // Turn on magnetometer 36 | Puck.magOn(); 37 | -------------------------------------------------------------------------------- /experiment35.js: -------------------------------------------------------------------------------- 1 | // Note: Google has now disabled Eddystone notifications because of abuse 2 | // by advertisers, so Eddystone devices will no longer appear as Android Notifications . 3 | // See https://android-developers.googleblog.com/2018/10/discontinuing-support-for-android.html 4 | // Google also shut down goo.gl, so you'll need to use bit.ly for new links instead 5 | 6 | // magnetism measured when nothing around 7 | var zeroMag = Puck.mag(); 8 | var wasDoorOpen = false; 9 | var doorOpenings = 0; 10 | 11 | function doorOpened() { 12 | doorOpenings++; 13 | require("ble_eddystone").advertise("goo.gl/D8sjLK#"+doorOpenings); 14 | } 15 | 16 | // Called when new magnetic field information is found 17 | function onMag(xyz) { 18 | // work out the distance from zero 19 | var x = xyz.x - zeroMag.x; 20 | var y = xyz.y - zeroMag.y; 21 | var z = xyz.z - zeroMag.z; 22 | // Work out the magnitude of the field 23 | var d = Math.sqrt(x*x + y*y + z*z); 24 | // check door open state 25 | var isDoorOpen = d<500; 26 | if (isDoorOpen != wasDoorOpen) { 27 | if (isDoorOpen) { 28 | doorOpened(); 29 | // flash green LED for open 30 | digitalPulse(LED2,1,100); 31 | } else { 32 | // flash red LED for close 33 | digitalPulse(LED1,1,100); 34 | } 35 | wasDoorOpen = isDoorOpen; 36 | } 37 | } 38 | 39 | // Set callback when magnetic field info is found 40 | Puck.on('mag', onMag); 41 | // Turn on magnetometer 42 | Puck.magOn(); 43 | -------------------------------------------------------------------------------- /experiment36.html: -------------------------------------------------------------------------------- 1 | 2 | Door Openings 3 | 4 |

5 | Door opened
6 | ?
7 | times... 8 |

9 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /experiment38a.js: -------------------------------------------------------------------------------- 1 | // drawing a square 2 | 3 | var StepperMotor = require("StepperMotor"); 4 | var motorx = new StepperMotor({ 5 | pins:[B3,B4,B5,A6] 6 | }); 7 | var motory = new StepperMotor({ 8 | pins:[B10,B13,B14,B15] 9 | }); 10 | 11 | motorx.moveTo(100, 1000, function() { 12 | motory.moveTo(100, 1000, function() { 13 | motorx.moveTo(0, 1000, function() { 14 | motory.moveTo(0, 1000, function() { 15 | console.log("Done!"); 16 | }); 17 | }); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /experiment38b.js: -------------------------------------------------------------------------------- 1 | // drawing a spiral 2 | 3 | var StepperMotor = require("StepperMotor"); 4 | var motorx = new StepperMotor({ 5 | pins:[B3,B4,B5,A6] 6 | }); 7 | var motory = new StepperMotor({ 8 | pins:[B10,B13,B14,B15] 9 | }); 10 | 11 | function moveTo(x,y,callback) { 12 | // Work out the distance in X and Y 13 | var dx = x - motorx.getPosition(); 14 | var dy = y - motory.getPosition(); 15 | // Work out the diagonal distance with pythagoras 16 | var d = Math.sqrt(dx*dx + dy*dy); 17 | // Work out how much time we've got to move 18 | var time = d * 1000 / motorx.stepsPerSec; 19 | // Set both motors moving 20 | motorx.moveTo(x, time); 21 | motory.moveTo(y, time, callback); 22 | } 23 | 24 | function spiral(r,ang) { 25 | if (ang>=Math.PI*24) return; 26 | moveTo(Math.sin(ang)*r, Math.cos(ang)*r, function() { 27 | spiral(r+0.2, ang+Math.PI/40); 28 | }); 29 | } 30 | spiral(0,0) 31 | -------------------------------------------------------------------------------- /experiment38c.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Making Things Smart Experiment 38 4 | 5 | 6 | 7 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /experiment38d.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Making Things Smart Experiment 38 4 | 5 | 6 | 7 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /experiment38e.js: -------------------------------------------------------------------------------- 1 | // Drawing a sin r/r pattern 2 | 3 | var StepperMotor = require("StepperMotor"); 4 | var motorx = new StepperMotor({ 5 | pins:[B3,B4,B5,A6] 6 | }); 7 | var motory = new StepperMotor({ 8 | pins:[B10,B13,B14,B15] 9 | }); 10 | 11 | function moveTo(x,y,callback) { 12 | var dx = x - motorx.getPosition(); 13 | var dy = y - motory.getPosition(); 14 | var d = Math.sqrt(dx*dx + dy*dy); 15 | var time = d * 1000 / motorx.stepsPerSec; 16 | motorx.moveTo(x, time); 17 | motory.moveTo(y, time, callback); 18 | } 19 | 20 | function sinrr(step, once) { 21 | // 'step' is going to keep increasing 22 | // make it 'scan' out in x and y 23 | var x = step % 100; 24 | var y = (step-x) / 100; 25 | if (y>=100) return; 26 | if (y&1) x = 100-x; 27 | // now center the coordinates on 0,0 28 | x -= 50; 29 | y -= 50; 30 | // Work out `r` - the radius 31 | // - but add a bit to `r` to avoid a divide by 0 below 32 | var r = Math.sqrt(x*x + y*y) + 0.1; 33 | // Make 'z' a fun mathematical formula - (sin r)/r in this case 34 | var z = 100 * Math.sin(-r/2) / r; 35 | // now work out some 3D coordinates 36 | var a = 0.4; // rotation in 'y' axis 37 | var b = 0.5; // rotation in 'x' axis 38 | var rx = Math.cos(a)*x + Math.sin(a)*y; 39 | var ry = Math.cos(a)*y - Math.sin(a)*x; 40 | var rz = Math.cos(b)*z + Math.sin(b)*ry; 41 | ry = Math.cos(b)*ry - Math.sin(b)*z; 42 | // and project into 2d 43 | var px = rx * 2000 / (100-ry); 44 | var py = rz * 2000 / (100-ry); 45 | 46 | moveTo(px, py, function() { 47 | if (!once) sinrr(step+1); 48 | }); 49 | } 50 | 51 | sinrr(0, true); 52 | -------------------------------------------------------------------------------- /experiment39.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Making Things Smart Experiment 39 4 | 5 | 6 | Load image
7 | 8 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /experiment39a.js: -------------------------------------------------------------------------------- 1 | var WIFI_NAME = ""; 2 | var WIFI_KEY = ""; 3 | var wifi; 4 | 5 | // Initialisation for Espruino WiFi ONLY 6 | function onInit() { 7 | wifi = require("EspruinoWiFi"); 8 | wifi.connect(WIFI_NAME, { password : WIFI_KEY }, function(err) { 9 | if (err) { 10 | console.log("Connection error: "+err); 11 | return; 12 | } 13 | console.log("Connected!"); 14 | wifi.getIP(function(err,ip) { 15 | console.log("IP address is http://"+ip.ip); 16 | createServer(); 17 | }); 18 | }); 19 | } 20 | 21 | // Initialisation for Espruino Pico + ESP8266 ONLY 22 | function onInit() { 23 | Serial1.setup(115200, { tx: B6, rx : B7 }); 24 | wifi = require("ESP8266WiFi_0v25").connect(Serial1, function(err) { 25 | if (err) throw err; 26 | console.log("Connecting to WiFi"); 27 | wifi.connect(WIFI_NAME, WIFI_KEY, function(err) { 28 | if (err) { 29 | console.log("Connection error: "+err); 30 | return; 31 | } 32 | console.log("Connected!"); 33 | wifi.getIP(function(err,ip) { 34 | console.log("IP address is http://"+ip.ip); 35 | createServer(); 36 | }); 37 | }); 38 | }); 39 | } 40 | 41 | // Create a web server on Port 80 42 | function createServer() { 43 | var http = require("http"); 44 | http.createServer(pageHandler).listen(80); 45 | } 46 | 47 | var mainPageContents = "Hello World"; 48 | 49 | // Called when a page is requested 50 | function pageHandler(req, res) { 51 | var info = url.parse(req.url, true); 52 | //print(info); 53 | if (info.path == "/") { 54 | res.writeHead(200); 55 | res.end(mainPageContents); 56 | } else { 57 | console.log("Page "+info.path+" not found"); 58 | res.writeHead(404); 59 | res.end("Not found"); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /experiment39b.js: -------------------------------------------------------------------------------- 1 | var WIFI_NAME = ""; 2 | var WIFI_KEY = ""; 3 | var wifi; 4 | 5 | // Initialisation for Espruino WiFi ONLY 6 | function onInit() { 7 | wifi = require("EspruinoWiFi"); 8 | wifi.connect(WIFI_NAME, { password : WIFI_KEY }, function(err) { 9 | if (err) { 10 | console.log("Connection error: "+err); 11 | return; 12 | } 13 | console.log("Connected!"); 14 | wifi.getIP(function(err,ip) { 15 | console.log("IP address is http://"+ip.ip); 16 | createServer(); 17 | }); 18 | }); 19 | } 20 | 21 | // Initialisation for Espruino Pico + ESP8266 ONLY 22 | function onInit() { 23 | Serial1.setup(115200, { tx: B6, rx : B7 }); 24 | wifi = require("ESP8266WiFi_0v25").connect(Serial1, function(err) { 25 | if (err) throw err; 26 | console.log("Connecting to WiFi"); 27 | wifi.connect(WIFI_NAME, WIFI_KEY, function(err) { 28 | if (err) { 29 | console.log("Connection error: "+err); 30 | return; 31 | } 32 | console.log("Connected!"); 33 | wifi.getIP(function(err,ip) { 34 | console.log("IP address is http://"+ip.ip); 35 | createServer(); 36 | }); 37 | }); 38 | }); 39 | } 40 | 41 | // Create a web server on Port 80 42 | function createServer() { 43 | var http = require("http"); 44 | http.createServer(pageHandler).listen(80); 45 | } 46 | 47 | 48 | // Everything above here is the same 49 | // ==================================== 50 | 51 | /* We're using an ES6 templated string here so 52 | we can store the whole webpage verbatim, otherwise 53 | we'd have to escape every single newline in the string. */ 54 | var mainPageContents = ` 55 | WiFi Plotter 56 | 57 | Load image 58 |
59 | 193 | `; 194 | 195 | // Called when a page is requested 196 | function pageHandler(req, res) { 197 | var info = url.parse(req.url, true); 198 | if (info.pathname == "/") { 199 | res.writeHead(200); 200 | res.end(mainPageContents); 201 | } else if (info.pathname == "/push") { 202 | // we got 203 | res.writeHead(200); 204 | var accepted = queueMove(info.query.pts.split(",")); 205 | res.end(accepted ? "ok" : "busy"); 206 | } else { 207 | console.log("Page "+info.path+" not found"); 208 | res.writeHead(404); 209 | res.end("Not found"); 210 | } 211 | } 212 | 213 | // Stepper motor handling 214 | var StepperMotor = require("StepperMotor"); 215 | var motorx = new StepperMotor({ 216 | pins:[B3,B4,B5,A6] 217 | }); 218 | var motory = new StepperMotor({ 219 | pins:[B10,B13,B14,B15] 220 | }); 221 | 222 | function moveTo(x,y,callback) { 223 | var dx = x - motorx.getPosition(); 224 | var dy = y - motory.getPosition(); 225 | var d = Math.sqrt(dx*dx + dy*dy); 226 | var time = d * 1000 / motorx.stepsPerSec; 227 | motorx.moveTo(x, time); 228 | motory.moveTo(y, time, callback); 229 | } 230 | 231 | var busy = false; 232 | var nextPositions = []; 233 | function queueMove(positions) { 234 | if (nextPositions.length>40) { 235 | // we already have a lot of positions queued 236 | console.log("Rejected positions"); 237 | return false; // don't take any more 238 | } else { 239 | // add something else onto the queue 240 | console.log("Queued "+(positions.length/2)+" positions"); 241 | for (var i=0;i0) { 255 | // there is - get a new position off our queue 256 | var nextPos = nextPositions.shift(); 257 | // go there 258 | moveTo(nextPos[0], nextPos[1], moveFinished); 259 | } else { 260 | // no - we're no longer busy 261 | busy = false; 262 | } 263 | } 264 | -------------------------------------------------------------------------------- /experiment4a.js: -------------------------------------------------------------------------------- 1 | // the 4 steps we're doing 2 | var steps = [0b1000, 0b0010, 0b0100, 0b0001]; 3 | // the step we're going to output next 4 | var step = 0; 5 | 6 | function doStep() { 7 | // output the step from the array 8 | digitalWrite(MTR, steps[step]); 9 | // move on to the next step 10 | step++; 11 | // but if there are no more steps, we must go to the beginning 12 | if (step >= steps.length) step = 0; 13 | } 14 | -------------------------------------------------------------------------------- /experiment4b.js: -------------------------------------------------------------------------------- 1 | // our pins 2 | var MTR = [B1,A7,A6,A5]; 3 | // the 4 steps we're doing 4 | var steps = [0b1000, 0b0010, 0b0100, 0b0001]; 5 | // the step we're going to output next 6 | var step = 0; 7 | // the interval we'll be using 8 | var interval; 9 | 10 | function start(rpm) { 11 | // just in case! 12 | stop(); 13 | // start our interval 14 | interval = setInterval(function() { 15 | // output the step from the array 16 | digitalWrite(MTR, steps[step]); 17 | // move on to the next step 18 | step++; 19 | // but if there are no more steps, we must go to the beginning 20 | if (step >= steps.length) step = 0; 21 | }, 60000/rpm*(steps.length)); 22 | /* revs per minute = 60*1000 seconds, but we have to call 23 | this function once for each step times to do a rev */ 24 | } 25 | 26 | function stop() { 27 | // remove interval if there was one 28 | if (interval) 29 | clearInterval(interval); 30 | interval = undefined; 31 | // turn off coils 32 | digitalWrite(MTR, 0b0000); 33 | } 34 | -------------------------------------------------------------------------------- /experiment5.js: -------------------------------------------------------------------------------- 1 | // our pins 2 | var MTR = [B1,A7,A6,A5]; 3 | // the 8 steps we're doing 4 | var steps = [0b1000, 0b1010, 0b0010, 0b0110, 0b0100, 0b0101, 0b0001, 0b1001]; 5 | // the step we're going to output next 6 | var step = 0; 7 | // the interval we'll be using 8 | var interval; 9 | 10 | function start(rpm) { 11 | // just in case! 12 | stop(); 13 | // start our interval 14 | interval = setInterval(function() { 15 | // output the step from the array 16 | digitalWrite(MTR, steps[step]); 17 | // move on to the next step 18 | step++; 19 | // but if there are no more steps, we must go to the beginning 20 | if (step >= steps.length) step = 0; 21 | }, 60000/rpm*(steps.length)); 22 | /* revs per minute = 60*1000 seconds, but we have to call 23 | this function once for each step times to do a rev */ 24 | } 25 | 26 | function stop() { 27 | // remove interval if there was one 28 | if (interval) 29 | clearInterval(interval); 30 | interval = undefined; 31 | // turn off coils 32 | digitalWrite(MTR, 0b0000); 33 | } 34 | -------------------------------------------------------------------------------- /experiment6.js: -------------------------------------------------------------------------------- 1 | // the last speed we calculated 2 | var rpm; 3 | 4 | function onChanged(e) { 5 | if (e.state) { 6 | // when the pin changes state to be high 7 | var timeDiff = e.time - lastPulseTime; 8 | lastPulseTime = e.time; 9 | rpm = 60 / timeDiff; 10 | digitalWrite(LED2, rpm < 900); 11 | } 12 | counter++; 13 | digitalWrite(LED1, e.state); 14 | } 15 | 16 | function onSecond(e) { 17 | // only light the LED if it's been a whole second without any movement (we must be stationary!) 18 | if (counter==0) digitalWrite(LED2, 1); 19 | counter=0; 20 | console.log(rpm); 21 | } 22 | 23 | setWatch(onChanged, SENSE, { edge:"both", repeat:true }); 24 | setInterval(onSecond, 1000); 25 | -------------------------------------------------------------------------------- /experiment7.js: -------------------------------------------------------------------------------- 1 | var SENSE = A8; 2 | var counter = 0; 3 | function onChanged(e) { 4 | counter++; 5 | if (counter&1) // remove this if your fan only flashes once per revolution 6 | digitalPulse(LED2, 1 , 2/*ms*/); 7 | } 8 | 9 | pinMode(SENSE, "input_pullup"); 10 | setWatch(onChanged, SENSE, { edge:"rising", repeat:true }); 11 | -------------------------------------------------------------------------------- /experiment8.js: -------------------------------------------------------------------------------- 1 | var SENSE = A8; 2 | var LIGHT = B6; 3 | var counter = 0; 4 | 5 | function onChanged(e) { 6 | counter++; 7 | if (counter&1) 8 | digitalPulse(LIGHT, 1 , 2/*ms*/); 9 | } 10 | 11 | digitalWrite(LIGHT, 0); 12 | pinMode(SENSE, "input_pullup"); 13 | setWatch(onChanged, SENSE, { edge:"rising", repeat:true }); 14 | -------------------------------------------------------------------------------- /experiment9a.js: -------------------------------------------------------------------------------- 1 | var SENSE = A8; 2 | var LIGHT = B6; 3 | var counter = 0; 4 | var pulses = 2;/*ms*/ 5 | 6 | function onChanged(e) { 7 | counter++; 8 | if (counter&1) 9 | digitalPulse(LIGHT, 1 , pulses); 10 | } 11 | 12 | digitalWrite(LIGHT, 0); 13 | pinMode(SENSE, "input_pullup"); 14 | setWatch(onChanged, SENSE, { edge:"rising", repeat:true }); 15 | -------------------------------------------------------------------------------- /experiment9b.js: -------------------------------------------------------------------------------- 1 | var SENSE = A8; 2 | var LIGHT = B6; 3 | var counter = 0; 4 | var pulses = [0.5, 2, 0.5, 2, 0.5];/*ms*/ 5 | var lastPulseTime; 6 | 7 | function onChanged(e) { 8 | counter++; 9 | if (counter&1) { 10 | var d = e.time - lastPulseTime; 11 | lastPulseTime = e.time; 12 | var p = pulses.map(function(t) { return t*d; }); 13 | digitalPulse(LIGHT, 1 , p); 14 | } 15 | } 16 | 17 | digitalWrite(LIGHT, 0); 18 | pinMode(SENSE, "input_pullup"); 19 | setWatch(onChanged, SENSE, { edge:"rising", repeat:true }); 20 | -------------------------------------------------------------------------------- /experiment9c.js: -------------------------------------------------------------------------------- 1 | var SENSE = A8; 2 | var LIGHT = B6; 3 | var counter = 0; 4 | var pulses = [0.5, 2, 0.5, 2, 0.5];/*ms*/ 5 | var lastPulseTime; 6 | 7 | function onChanged(e) { 8 | counter++; 9 | if (counter&1) { 10 | var d = e.time - lastPulseTime; 11 | lastPulseTime = e.time; 12 | var p = pulses.map(function(t) { return t*d; }); 13 | digitalPulse(LIGHT, 1 , p); 14 | } 15 | } 16 | 17 | function animate() { 18 | var l = 50 + 40*Math.sin(getTime()); 19 | pulses = [5, l, 5, 100-l, 5]; 20 | } 21 | 22 | 23 | digitalWrite(LIGHT, 0); 24 | pinMode(SENSE, "input_pullup"); 25 | setWatch(onChanged, SENSE, { edge:"rising", repeat:true }); 26 | setInterval(animate,100) 27 | -------------------------------------------------------------------------------- /experiment9d.js: -------------------------------------------------------------------------------- 1 | var SENSE = A8; 2 | var LIGHT = B6; 3 | var counter = 0; 4 | var blades = 7; // the number of fan blades you have 5 | var t = (1000 - blades*5) / blades; 6 | var pulses = [5]; 7 | for (var i=0;i