Graphical roulette

このエントリーをはてなブックマークに追加

This is Graphical roulette.
Push button and start rotating roulette. Push once more, stop rotating and beep!

Circit

It is only wired speaker and button.

The pin no of wired are written on program.

button = obniz.wired("Button", {signal:6 , gnd:7 });
speaker = obniz.wired("Speaker", {signal:0 , gnd: 1});

Rotate image

Rotate rulette image.

On HTML, you can use "css transform".
For example , this is the code of rotate image 90 degree.

document.getElementById("roulette").style = "transform:rotate(90deg);";

To start and stop rotate slowly, add a var speed for rotate degree per frame.

let speed = 0;
  let deg = 0;
  function rotate(){
    deg += speed;
      document.getElementById("roulette").style = "transform:rotate("+deg+"deg);";

  }
  setInterval(rotate,10);

Beep

Do you want to beep on the roulette no change?
With this, you can beep on 440Hz 10ms.

      speaker.play(440);
      await obniz.wait(10);
      speaker.stop(); 

This is how to know on change of roulette no.

if( Math.floor((deg + speed) / (360/7.0)) -  Math.floor(deg / (360/7.0)) >= 1){
      onRouletteChange();
}

So, this is the code of rotate and beep.



  let speed = 0;
  let deg = 0;
  function rotate(){
    //on change value
    if( Math.floor((deg + speed) / (360/7.0)) -  Math.floor(deg / (360/7.0)) >= 1){
      onRouletteChange();
    }
    deg += speed;
      document.getElementById("roulette").style = "transform:rotate("+deg+"deg);";

  }
  setInterval(rotate,10);

  async function onRouletteChange(){
    if(!speaker){return;}
      speaker.play(440);
      await obniz.wait(10);
      speaker.stop(); 
  }

Start on button pushed.

To know button state, add var buttonStateand set value of current button state.

button.onchange = function(pressed){
    buttonState = pressed;
  };

And also add var phase for current state of roulette.

phase is setted one of this.

const PHASE_WAIT_FOR_START = 0; 
const PHASE_ROTATE = 1;
const PHASE_STOPPING = 2;
const PHASE_STOPPED = 3;

For example, when phase is PHASE_WAIT_FOR_START and you want to next phase.

if(phase == PHASE_WAIT_FOR_START){
    speed = 0;
    if(buttonState){
       phase = PHASE_ROTATE;
    }
}

To speed up rulette, change var speed .

if(phase == PHASE_ROTATE){
    speed = speed+0.5;
}

To speed down rulette, change var speed .

if(phase == PHASE_STOPPING){    
    speed = speed-0.2;
}

Those are component of roulette. Let's make it!

Program

<!-- HTML Example -->

<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://unpkg.com/obniz@2.0.2/obniz.js" crossorigin="anonymous"></script>
  <style>
 
#roulette {
  position : absolute ;
   padding:0px 0 0;
   width:300px;
}

#roulette  img {
   width:300px;
}
#wrapper{
   			position:absolute;
}
#hari {
  position : absolute ;
   top:-20px;
   left:134px;
  z-index : 10;
}
  </style>
</head>
<body>

<div id="obniz-debug"></div>
<h1>obniz roulette</h1>

  <div id="wrapper">
<div id="hari"><img src="https://web.obniz.io/wp-content/uploads/2018/07/pin-1.png"></div>

<div id="roulette"><img src="https://web.obniz.io/wp-content/uploads/2018/07/roulette@3x.png"/></div>

  </div>


<script>
var obniz = new Obniz("OBNIZ_ID_HERE");
let button,speaker;
let buttonState = false;
obniz.onconnect = async function () {

  button = obniz.wired("Button", {signal:6 , gnd:7 });
  speaker = obniz.wired("Speaker", {signal:0 , gnd: 1});
  
  button.onchange = function(pressed){
    buttonState = pressed;
  };
  
  obniz.display.clear();
  obniz.display.print("Start Roulette");
  
}

const PHASE_WAIT_FOR_START = 0; 
const PHASE_ROTATE = 1;
const PHASE_STOPPING = 2;
const PHASE_STOPPED = 3;
let phase = PHASE_WAIT_FOR_START; 
let stopCount = 0;
  
obniz.repeat(async function(){
  if(!button){return;}
  
  if(phase == PHASE_WAIT_FOR_START){
    speed = 0;
  	if(buttonState){
       phase = PHASE_ROTATE;
      
       // wait for release button
      await new Promise((resolve)=>{
        setInterval(()=>{
        	if(!buttonState){
      			resolve();
      		}
        },10);
      });
    }
  }else if(phase == PHASE_ROTATE){
    speed = Math.min(speed+0.5, 5);
    
    if(buttonState){
      phase = PHASE_STOPPING;
      stopCount = 0;
    }
    
  }else if(phase == PHASE_STOPPING){
    
    speed = Math.max(speed-0.2,0);
    if(speed == 0 ){
    	phase = PHASE_STOPPED;
    }
    
  }else if(phase == PHASE_STOPPED){
    for(let i = 0; i < 15;i++){
    	speaker.play(440*3);
  		await obniz.wait(10);
  		speaker.stop(); 
  		await obniz.wait(100);
    }
    phase = PHASE_WAIT_FOR_START;
  }       
             
}, 100);
  
  
  let speed = 0;
  let deg = 0;
  function rotate(){
    if( Math.floor((deg + speed) / (360/7.0)) -  Math.floor(deg / (360/7.0)) >= 1){
      onRouletteChange();
    }
    deg += speed;
  	document.getElementById("roulette").style = "transform:rotate("+deg+"deg);";
    
  }
  setInterval(rotate,10);
  
  async function onRouletteChange(){
    if(!speaker){return;}
  	speaker.play(440);
  	await obniz.wait(10);
  	speaker.stop(); 
  }
  
</script>
</body>
</html>

Run Now

The html will be opened to run a program.