趣味电子绕环游戏(Wire Loop Game)

官方教程链接:http://www.espruino.com/Pico+Wire+Loop+Game

所需材料
1. Espruino开发板一个
2. Nokia 5110 LCD一个
3. 蜂鸣器一个
4. 面包板一个
5. 按钮开关一个
6. 直径0.6mm的实心导线1米左右

LCD接线方法:

LCD pinPin typeEspruino Board
GNDGNDGND
LIGHTAnyA0
VCC3.3vA1
CLKSPI SCKB3
DINSPI MOSIB5
DCAnyB6
CEAnyB7
RSTAnyB8

其他部分接线方法请参考代码。

因为官方用的是Espruino Pico,我用的是Espruino Board,所以接线略有不同,另外我的这个LCD没法直接使用官方的库,我就把LCD的初始化代码放在onInit函数里了。

A0.write(1); // LCD Light
A1.write(1); // LCD VCC
var LOOP = C0; // the pin we've got our loop attached to
var SPEAKER = B9; // where the speaker is attached
var BTN_RST = C1; // where the Reset button is attached

var g;         // the LCD's graphics
var score = 0; // current score

function drawScore() {
  g.clear();
  // draw the score
  g.setFontVector(40);
  g.drawString(score,(g.getWidth()-g.stringWidth(score))/2,0);
  // send the graphics to the display
  g.flip();
}


// flash and make a sound, and call the callback when done
function hasHit(callback) {
  // increment the score...
  score++;

  var i = 1;

  // This will make the beeping and flashing
  function siren() {
    if (i>7) {
      clearInterval(interval);
      digitalWrite(LED1, 0); // turn the LED off
      // set normal colours on LCD
      g.setColor(1);
      g.setBgColor(0);
      // turn the sound off
      digitalRead(SPEAKER);
      callback();
      return;
    }

    // every other time around the loop:
    if (i&1) {
      digitalWrite(LED1, 1); // turn red LED on
      // set inverted colours on LCD
      g.setColor(0);
      g.setBgColor(1);
      // beep high frequency
      analogWrite(SPEAKER, 0.5, {freq:1000});
    } else {
      digitalWrite(LED1, 0); // turn the LED off
      // set normal colours on LCD
      g.setColor(1);
      g.setBgColor(0);
      // beep low frequency
      analogWrite(SPEAKER, 0.5, {freq:700});
    }

    // draw the text 'hit' on the LCD
    g.clear();
    g.setFontVector(40);
    g.drawString("Hit!",(g.getWidth()-g.stringWidth("Hit!"))/2,0);
    g.flip();

    i++;
  }
  // call the siren function every so often (and call it once immediately)
  var interval = setInterval(siren, 300);
  siren();
}


function onInit() {
  // Setup SPI for LCD
  SPI1.setup({ baud: 1000000, sck:B3, mosi:B5 });
  g = Graphics.createArrayBuffer(84,48,1,{vertical_byte:true});
  var spi = SPI1;
  var dc = B6;
  var ce = B7;
  var rst = B8;
  digitalPulse(rst, 0, 10); // pulse reset low
  setTimeout(function() {
    digitalWrite(dc,0); // cmd
    spi.send(
      [0x21, // fnset extended
      0x80 | 0x25, // setvop (experiment with 2nd val to get the right contrast)
      0x14, // setbias 4
      0x04 | 0x02, // temp control
      0x20, // fnset normal
      0x08 | 0x04], ce); // dispctl normal
  }, 100);
  g.flip = function () {
    for (var i=0;i<6;i++) {
      digitalWrite(dc,0); // cmd
      spi.send(0x40|i, ce); // Y addr
      spi.send(0x80, ce); // X addr
      digitalWrite(dc,1); // data
      spi.send(new Uint8Array(g.buffer,i*84,84), ce);
    }
  };
  drawScore();
  startWatchingLoop();
}

// Add the internal pull-up resistor to the loop, so when it touches the wire (which is GND) it'll get pulled down
pinMode(LOOP, "input_pullup");
pinMode(BTN_RST, "input_pulldown");
// This code watches the 'loop' to see if it has touched the wire
var loopWatch;
function startWatchingLoop() {
  // first, ensure we don't start watching the wire loop twice
  if (loopWatch) clearWatch(loopWatch);
  loopWatch = setWatch(function() {
    loopWatch = undefined;
    // now if we've touched, flash everything and make noises
    hasHit(function() {
      // When that's done, draw the score and start watching the loop again
      drawScore();
      startWatchingLoop();
    });
  }, LOOP, { repeat: false, edge: "falling" });
}

// When button is pressed, reset the game:
setWatch(function() {
  clearInterval();
  digitalRead(SPEAKER); // make sure speaker is off
  score = 0;
  drawScore();
  startWatchingLoop();
}, BTN_RST, { repeat: true, edge: "rising", debounce: 50 });


// Finally, start everything going
onInit();

在Web IDE中将这些代码上传至Espruino之后,然后在Web IDE左边的console中执行一下save()函数就可以把这些代码烧录到espruino了~

用Espruino做的极简遥控车

很早就想做一个遥控车玩玩,还因此买了一块Arduino Mega 2560,结果由于种种原因,最终没有做成,
Arduino放在家里吃灰了。

开始接触Espruino之后,做个遥控车的想法又回来了,因为Espruino玩起来确实方便,这个用过的人应该
都知道哈~

买了一个遥控器模块,一个两驱的小车套件。代码很简单,但是确实实现了简单的遥控功能,至于避碍,
巡线啥滴[就以后再说吧~
接线方法请参考代码里的相关参数~

function up()
{
  digitalWrite([C0,C1,C2,C3],0b1001);
}
function down()
{
  digitalWrite([C0,C1,C2,C3],0b0110);
}
function left()
{
  digitalWrite([C0,C1,C2,C3],0b1010);
}
function right()
{
  digitalWrite([C0,C1,C2,C3],0b0101);
}
function stop()
{
  digitalWrite([C0,C1,C2,C3],0b0000);
}
setWatch("right()",A2,{ repeat:true, edge:'rising' });
setWatch("stop()",A2,{ repeat:true, edge:'falling' });
setWatch("down()",A3,{ repeat:true, edge:'rising' });
setWatch("stop()",A3,{ repeat:true, edge:'falling' });
setWatch("up()",A4,{ repeat:true, edge:'rising' });
setWatch("stop()",A4,{ repeat:true, edge:'falling' });
setWatch("left()",A5,{ repeat:true, edge:'rising' });
setWatch("stop()",A5,{ repeat:true, edge:'falling' });
//setWatch(function(){},A6,{ repeat:true, edge:'rising' });
//setWatch(function(){},A6,{ repeat:true, edge:'falling' });
function onInit()
{
  analogWrite(A0,1);
  analogWrite(A1,1);
}

Espruino简介

Espruino的Logo:

Espruino的Logo很cool哦~ 咖啡杯代表JavaScript,杯底的引脚代表开源硬件。

Espruino在国外知名的众筹平台KickStarter上发布之后才被人知晓,其发明人是来自英国的Gordon Williams。
Espruino是一种运行在微控制器上的软件,实现了Javascript解释器的功能,因此你只要会用Javascript,
就可以对微控制器进行编程,释放自己的创意,DIY出自己的电子作品。

Espruino开发板是一个小电脑,任何人都可以利用它去控制身边的东西。它的JavaScript解释器给你实时的
反馈,因此不管你是否拥有类似的编程经验,你都可以进行试验和开发。即使你之前从来没有编写过代码,
你也能利用图形化的代码编辑器去构建自己的程序而不用键入一个字符。只要把你的Espruino开发板插到你
的电脑上,使用Chrome Web IDE或你自己喜欢的终端应用程序,你就可以马上编写程序了。
你可以使用Web IDE自动下载JavaScript模块,这些模块将帮助你去操作其对应的硬件,比如显示器和无线
模组。
Espruino的事件驱动特性使得它可以尽可能的省电,低至0.1mA的功耗允许你的案子使用普通的5号电池就能
运行好几年,如果用上一个小的太阳能电池,那就可以永久使用了。
Espruino的软件和硬件都是开源的。

特性
1. 适用于Windows,Linux,MacOS和Android(透过蓝牙或USB OTG连接)
2. 比名片的一半还要小-只有54mm x 41mm
3. 使用流行的JavaScript语言,Espruino支持字串,图,对象和动态数组
4. 72Mhz ARM微控制器,内置256KB闪存和48KB内存
5. 微型USB接口,微型SD卡接口,适应宽电压范围输入(从 3.6v 到 15v)的JST电池接口
6. 红色,绿色和蓝色的LED灯,两个按键(其中一个默认为复位键)
7. 焊接上一个HC-05蓝牙模组(开发板上默认没有该模组),就可以透过无线对Espruino编程和debug!
8. 44个GPIO针脚,针脚间隔0.1英寸(0.254厘米),26个PWM针脚,16个ADC针脚,5个USART接口,3个SPI
   接口,2个I2C接口和2个DAC接口
9. 功耗:运行 35mA,待机 12mA,深度待机0.1mA
10. 原型区域可以焊接伺服器头,无线模组和小外型集成电路表面贴装组件,例如马达驱动器
11. 内建TI CC3000 WiFi模组(开发板上默认没有该模组),还内建了一个支持向量字体的图形库
12. 开源软件和硬件
13. Espruino网站提供完整文档,很多教程和一个活跃的论坛

Espruino支持的兼容开发板
STM32VLDISCOVERY
STM32F3DISCOVERY
STM32F4DISCOVERY
OLIMEXINO-STM32 / LeafLabs Maple RBT6
HY-STM32 2.4 inch LCD Board (VET6)
HY-STM32 2.8 inch LCD Board (RBT6)
HY-MiniSTM32V 3.2 inch LCD Board (VCT6)

一个用户自定义键,一个复位键

红绿蓝三只LED灯

电池接口 可以直接由电池供电

SMD原型区域 可以焊接一些芯片在上面

微型USB接口 透过这个和电脑相连

微型SD卡插槽

可选的蓝牙模组可以焊接在这里 有了这个就可以透过无线进行编程和debug了

伺服器马达插头

焊接在SMD原型区域的L293D马达控制器

焊接上HC-05蓝牙模组的Espruino开发板

开发板上的接口资源非常丰富

插上开发板就马上可以进行开发,无需繁琐的设置,只要有个支持串口的终端程序就可以了

推荐使用Espruino的Chrome Web IDE,支持代码高亮,出错提示。

Espruino的Chrome Web IDE甚至提供了类似Scratch语言的完全图形化开发环境

总结一下Espruino的特点:
1. 使用JavaScript进行编程,只要会用JavaScript就能做出自己的创意电子作品。
2. 不需要安装特殊的软件和做繁琐的设定,插上开发板,打开Chrome浏览器,安装Espruino的Web IDE插件,
   然后就可以进行实验和开发了。
3. 键入的代码可以立即执行,看到结果,做实验和debug起来都非常方便。
4. 使用的命令和Arduino相似,Arduino开发者可以很快掌握Espruino的开发。
5. Espruino兼容的开发板比较多,也很便宜,100块左右人民币就能买到。原装的Espruino开发板要240块
   人民币,比较贵,买兼容的玩玩就行。
6. 软件开源,方便用户将其移植到其他硬件平台。
7. 硬件开源,用户可以自己制作Espruino开发板,比从经销商那里买要便宜很多。

注:以上资料大部分翻译自Espruino官网 www.espruino.com
       该译文非逐句翻译,而是按照自己的理解翻译,请勿中英一一对照。

基于DSM501A的空气质量指数(AQI)计算装置

基于DSM501A的空气质量指数(AQI)计算装置
作者:Espruino中文社区 lawrencedon

使用的模块:DSM501A
接线方法:
DSM501A     Espruino
pin1 ——– 不用接
pin2 ——– A1
pin3 ——– Bat
pin4 ——– A0
pin5 ——– GND
这里用A0,A1其实是有点不妥的,因为这两个针脚是3.3v tolerant,而DSM501的输出高电平可以达到4.7v。
可以使用5v tolerant的针脚来做该实验。在下面链接里的PINOUT图中没有标注3.3v的针脚都是5v tolerant的。
http://www.espruino.com/ReferenceESPRUINOBOARD
计算颗粒浓度和AQI的公式来自https://github.com/alexjx/AqiMon
//基于DSM501A的空气质量指数(AQI)计算装置
//使用的模块:DSM501A
//接线方法:
// DSM501A       Espruino
// pin1 -------- 不用接
// pin2 -------- A1
// pin3 -------- Bat
// pin4 -------- A0
// pin5 -------- GND
//计算颗粒浓度和AQI的公式来自https://github.com/alexjx/AqiMon
//作者:Espruino中文社区 lawrencedon

var pm10 = 0;
var pm25 = 0;
var pm10_weight = 0;
var pm25_weight = 0;
var aqi = 0;
var P25Weight = 0;
setWatch(function(e){
  var lowtime0=(e.time-e.lastTime)*1000;
  if(lowtime0>=10 && lowtime0<=90)
  {
    //console.log("pm10: " + lowtime0);
    pm10+=lowtime0;
  }
},A1,{repeat:true,edge:"rising"});
setWatch(function(e){
  var lowtime1=(e.time-e.lastTime)*1000;
  if(lowtime1>=10 && lowtime1<=90)
  {
    //console.log("pm25: " + lowtime1);
    pm25+=lowtime1;
  }
},A0,{repeat:true,edge:"rising"});
setInterval(function(e){
  pm10_weight = 0.30473 * Math.pow((pm10/30000)*100, 3) - 2.63943 * Math.pow((pm10/30000)*100, 2) + 102.60291 * (pm10/30000)*100 - 3.49616;

  pm25_weight = 0.30473 * Math.pow((pm25/30000)*100, 3) - 2.63943 * Math.pow((pm25/30000)*100, 2) + 102.60291 * (pm25/30000)*100 - 3.49616;

    P25Weight = pm10_weight - pm25_weight;

   if (P25Weight>= 0 && P25Weight <= 15.4) {
  aqi = 0 +(50.0 / 15.5 * P25Weight);
} else if (P25Weight > 15.5 && P25Weight <= 40.5) {
  aqi = 50 + (50.0 / 25.0 * (P25Weight - 15.5));
} else if (P25Weight > 40.5 && P25Weight <= 65.5) {
  aqi = 100 + (50.0 / 25.0 * (P25Weight - 40.5));
} else if (P25Weight > 65.5 && P25Weight <= 150.5) {
  aqi = 150 + (50.0 / 85.0 * (P25Weight - 65.5));
} else if (P25Weight > 150.5 && P25Weight <= 250.5) {
  aqi = 200 + (100.0 / 100.0 * (P25Weight - 150.5));
} else if (P25Weight > 250.5 && P25Weight <= 350.5) {
  aqi = 300 + (100.0 / 100.0 * (P25Weight - 250.5));
} else if (P25Weight > 350.5 && P25Weight <= 500.0) {
  aqi = 400 + (100.0 / 150.0 * (P25Weight - 350.5));
} else if (P25Weight > 500.0) {
  aqi = 500 + (500.0 / 500.0 * (P25Weight - 500.0));
} else {
  aqi = 0;
}
  console.log("__________AQI:" + aqi + "__________");
    pm10=0;pm25=0;
},30000);