Add Processing Sketchs
Add Processing Sketchs and Processing tutorial
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
/******************************************************************************* //<>//
|
||||
* Sketch App_01_1_1_Oscilloscope
|
||||
* Author Freenove (http://www.freenove.com)
|
||||
* Date 2016/08/26
|
||||
******************************************************************************
|
||||
* Brief
|
||||
* This sketch is used to make an oscilloscope
|
||||
*************************************p*****************************************
|
||||
* Copyright
|
||||
* Copyright © Freenove (http://www.freenove.com)
|
||||
* License
|
||||
* Creative Commons Attribution ShareAlike 3.0
|
||||
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
|
||||
******************************************************************************
|
||||
*/
|
||||
import processing.io.*;
|
||||
|
||||
PCF8591 pcf = new PCF8591(0x48);
|
||||
int[] analogs; // Analog data send from serial device
|
||||
int analogsCount; // Length of analogs[] array
|
||||
int voltage = 0; // Voltage
|
||||
int hMult = 1; // Horizontal zoom ratio, relative to 1 second
|
||||
boolean pause = false; // Storage is suspended display
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(530, 290);
|
||||
background(102);
|
||||
textAlign(CENTER, CENTER);
|
||||
textSize(64);
|
||||
text("Starting...", width / 2, (height - 40) / 2);
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20);
|
||||
textAlign(LEFT, CENTER);
|
||||
|
||||
analogsCount = width / 2;
|
||||
analogs = new int[analogsCount];
|
||||
for (int i = 0; i < analogsCount; i++)
|
||||
analogs[i] = -1;
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
|
||||
int analog = pcf.analogRead(0); //serialDevice.requestAnalog();
|
||||
if (analog != -1)
|
||||
{
|
||||
// GUI
|
||||
background(102);
|
||||
textSize(12);
|
||||
text("↑: Zoom up", 120, 6);
|
||||
text("↓: Zoom down", 120, 20);
|
||||
text("Enter: Visit Freenove website", 220, 6);
|
||||
text("Space: Pause", 220, 20);
|
||||
textSize(16);
|
||||
// Voltage scale text
|
||||
for (int i = 5; i >= 0; i--)
|
||||
{
|
||||
text(i, 5, 280 - i * 50 - 2);
|
||||
if (i == 5)
|
||||
text("V", 15, 280 - i * 50 - 2);
|
||||
}
|
||||
// Horizontal line
|
||||
stroke(64, 64, 64);
|
||||
for (int i = 0; i < 6; i++)
|
||||
line(30, 30 + i * 50, width, 30 + i * 50);
|
||||
// Vertical line time text
|
||||
text(1000 / hMult + "ms", 40, 15 - 2);
|
||||
// Vertical line
|
||||
for (int i = 0; i < (width - 30) / 50 + 1; i++)
|
||||
line(30 + i * 50, 30, 30 + i * 50, height - 10);
|
||||
|
||||
if (!pause)
|
||||
{
|
||||
// Prepare wave data
|
||||
for (int i = 0; i < analogsCount - 1; i++)
|
||||
analogs[i] = analogs[i + 1];
|
||||
analogs[analogsCount - 1] = height - 10 - analog * (height - 10 - 30) / 255;
|
||||
// Voltage text
|
||||
voltage = analog * 500 / 255;
|
||||
}
|
||||
String sVoltage = voltage / 100 + "." + voltage / 10 % 10 + voltage % 10;
|
||||
text(sVoltage + "V", width - 48, 15 - 2);
|
||||
// Wave line
|
||||
stroke(0, 255, 0);
|
||||
for (int i = width; i > 30; i -= hMult * width / analogsCount)
|
||||
{
|
||||
int a = i / hMult + width * (hMult - 1) / hMult;
|
||||
a = a * analogsCount / width - 1;
|
||||
if (analogs[a] >= 0 && analogs[a - 1] >= 0)
|
||||
line(i, analogs[a], i - hMult * width / analogsCount, analogs[a - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void keyPressed()
|
||||
{
|
||||
if (key == CODED)
|
||||
{
|
||||
if (keyCode == UP)
|
||||
{
|
||||
if (hMult == 1)
|
||||
hMult = 2;
|
||||
else if (hMult == 2)
|
||||
hMult = 5;
|
||||
else if (hMult == 5)
|
||||
hMult = 10;
|
||||
}
|
||||
else if (keyCode == DOWN)
|
||||
{
|
||||
if (hMult == 10)
|
||||
hMult = 5;
|
||||
else if (hMult == 5)
|
||||
hMult = 2;
|
||||
else if (hMult == 2)
|
||||
hMult = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (key == ' ')
|
||||
{
|
||||
pause = !pause;
|
||||
if (!pause)
|
||||
{
|
||||
for (int i = 0; i < analogsCount; i++)
|
||||
analogs[i] = -1;
|
||||
}
|
||||
}
|
||||
else if (key == '\n' || key == '\r')
|
||||
{
|
||||
link("http://www.freenove.com");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*****************************************************
|
||||
* Filename : PCF8591
|
||||
* Description : class PCF8591,DAC and ADC
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/20
|
||||
*****************************************************/
|
||||
|
||||
class PCF8591 {
|
||||
private int address;
|
||||
private I2C i2c;
|
||||
//constructor,Parameters for the PCF8591 I2C address
|
||||
public PCF8591(int addr) {
|
||||
address = addr;
|
||||
i2c = new I2C(I2C.list()[0]);
|
||||
}
|
||||
//Read the ADC value of one channel
|
||||
public int analogRead(int chn) {
|
||||
int result = 0;
|
||||
i2c.beginTransmission(address);
|
||||
constrain(chn, 0, 3);
|
||||
i2c.write(0x40 | chn);
|
||||
try {
|
||||
byte[] in = i2c.read(1);
|
||||
result = in[0]&0xff;
|
||||
}
|
||||
catch(Exception e) {
|
||||
println(e);
|
||||
}
|
||||
i2c.endTransmission();
|
||||
return result;
|
||||
}
|
||||
//Read the ADC value of all channels
|
||||
public byte[] analogRead() {
|
||||
i2c.beginTransmission(address);
|
||||
i2c.write(0x44);
|
||||
i2c.endTransmission();
|
||||
byte[] in = i2c.read(4);
|
||||
return in;
|
||||
}
|
||||
//Write the DACvalue
|
||||
public void analogWrite(int data) {
|
||||
i2c.beginTransmission(address);
|
||||
i2c.write(0x40);
|
||||
i2c.write(data);
|
||||
i2c.endTransmission();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/******************************************************************************* //<>//
|
||||
* Sketch App_02_1_1_Ellipse
|
||||
* Author Freenove (http://www.freenove.com)
|
||||
* Date 2016/08/26
|
||||
******************************************************************************
|
||||
* Brief
|
||||
* This sketch is used to control a 2D ellipse
|
||||
******************************************************************************
|
||||
* Copyright
|
||||
* Copyright © Freenove (http://www.freenove.com)
|
||||
* License
|
||||
* Creative Commons Attribution ShareAlike 3.0
|
||||
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
|
||||
******************************************************************************
|
||||
*/
|
||||
import processing.io.*;
|
||||
PCF8591 pcf = new PCF8591(0x48);
|
||||
void setup()
|
||||
{
|
||||
size(360, 360);
|
||||
background(102);
|
||||
textAlign(CENTER, CENTER);
|
||||
textSize(64);
|
||||
text("Starting...", width / 2, (height - 40) / 2);
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20);
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
int[] analogs = new int[2];
|
||||
analogs[0] = pcf.analogRead(0);
|
||||
analogs[1] = pcf.analogRead(1);
|
||||
if (analogs != null)
|
||||
{
|
||||
background(102);
|
||||
drawEllipse(analogs[0], analogs[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void drawEllipse(int x, int y)
|
||||
{
|
||||
int maxDiameter = 280;
|
||||
|
||||
fill(255, 255, 255);
|
||||
textAlign(CENTER, CENTER);
|
||||
textSize(16);
|
||||
text("Press Enter to visit www.freenove.com", width / 2, height - 20);
|
||||
text("X: " + x, width / 2 - 30, 20);
|
||||
text("Y: " + y, width / 2 + 30, 20);
|
||||
|
||||
x = x * maxDiameter / 255;
|
||||
y = y * maxDiameter / 255;
|
||||
fill(227, 118, 12);
|
||||
ellipse(width / 2, height / 2, x, y);
|
||||
}
|
||||
|
||||
void keyPressed()
|
||||
{
|
||||
if (key == '\n' || key == '\r')
|
||||
{
|
||||
link("http://www.freenove.com");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*****************************************************
|
||||
* Filename : PCF8591
|
||||
* Description : class PCF8591,DAC and ADC
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/20
|
||||
*****************************************************/
|
||||
|
||||
class PCF8591 {
|
||||
private int address;
|
||||
private I2C i2c;
|
||||
//constructor,Parameters for the PCF8591 I2C address
|
||||
public PCF8591(int addr) {
|
||||
address = addr;
|
||||
i2c = new I2C(I2C.list()[0]);
|
||||
}
|
||||
//Read the ADC value of one channel
|
||||
public int analogRead(int chn) {
|
||||
int result = 0;
|
||||
i2c.beginTransmission(address);
|
||||
constrain(chn, 0, 3);
|
||||
i2c.write(0x40 | chn);
|
||||
try {
|
||||
byte[] in = i2c.read(1);
|
||||
result = in[0]&0xff;
|
||||
}
|
||||
catch(Exception e) {
|
||||
println(e);
|
||||
}
|
||||
i2c.endTransmission();
|
||||
return result;
|
||||
}
|
||||
//Read the ADC value of all channels
|
||||
public byte[] analogRead() {
|
||||
i2c.beginTransmission(address);
|
||||
i2c.write(0x44);
|
||||
i2c.endTransmission();
|
||||
byte[] in = i2c.read(4);
|
||||
return in;
|
||||
}
|
||||
//Write the DACvalue
|
||||
public void analogWrite(int data) {
|
||||
i2c.beginTransmission(address);
|
||||
i2c.write(0x40);
|
||||
i2c.write(data);
|
||||
i2c.endTransmission();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* Sketch App_03_1_1_Pong_Game
|
||||
* Author Freenove (http://www.freenove.com)
|
||||
* Date 2016/08/26
|
||||
******************************************************************************
|
||||
* Brief
|
||||
* This sketch is used to play pong game
|
||||
******************************************************************************
|
||||
* Copyright
|
||||
* Copyright © Freenove (http://www.freenove.com)
|
||||
* License
|
||||
* Creative Commons Attribution ShareAlike 3.0
|
||||
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
|
||||
******************************************************************************
|
||||
*/
|
||||
import processing.io.*;
|
||||
|
||||
PCF8591 pcf = new PCF8591(0x48);
|
||||
|
||||
int winScore = 3;
|
||||
float acceleration = 0.5;
|
||||
float deviate = 1;
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
Ball ball;
|
||||
Paddle lPaddle, rPaddle;
|
||||
int gameState = GameState.WELCOME;
|
||||
int lScore, rScore;
|
||||
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
background(102);
|
||||
textAlign(CENTER, CENTER);
|
||||
textSize(64);
|
||||
text("Starting...", width / 2, (height - 40) / 2);
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20);
|
||||
|
||||
ball = new Ball(10);
|
||||
lPaddle = new Paddle(new Size(12, 80), 12);
|
||||
rPaddle = new Paddle(new Size(12, 80), width - 12);
|
||||
|
||||
}
|
||||
|
||||
void draw() {
|
||||
int[] analogs = new int[2];
|
||||
analogs[0] = pcf.analogRead(0);
|
||||
analogs[1] = pcf.analogRead(1);
|
||||
if (analogs != null)
|
||||
{
|
||||
lPaddle.position.y = analogs[0] * height /255;
|
||||
rPaddle.position.y = analogs[1] * height /255;
|
||||
}
|
||||
|
||||
background(102);
|
||||
if (gameState == GameState.WELCOME)
|
||||
{
|
||||
showGUI();
|
||||
lPaddle.display();
|
||||
rPaddle.display();
|
||||
showInfo("Pong Game");
|
||||
}
|
||||
else if (gameState == GameState.PLAYING)
|
||||
{
|
||||
ball.updata();
|
||||
calculateGame();
|
||||
showGUI();
|
||||
ball.display();
|
||||
lPaddle.display();
|
||||
rPaddle.display();
|
||||
}
|
||||
else if (gameState == GameState.PLAYER1WIN)
|
||||
{
|
||||
showGUI();
|
||||
lPaddle.display();
|
||||
rPaddle.display();
|
||||
showInfo("Player 1 win!");
|
||||
}
|
||||
else if (gameState == GameState.PLAYER2WIN)
|
||||
{
|
||||
showGUI();
|
||||
lPaddle.display();
|
||||
rPaddle.display();
|
||||
showInfo("Player 2 win!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void showInfo(String info)
|
||||
{
|
||||
rectMode(CENTER);
|
||||
stroke(0, 0, 0);
|
||||
fill(0, 0, 0, 50);
|
||||
rect(width / 2, height / 2, width / 2, height / 3);
|
||||
fill(255, 255, 255);
|
||||
textSize(24);
|
||||
textAlign(CENTER, CENTER);
|
||||
text(info, width / 2, height / 2 - 24);
|
||||
text("Press Space to start", width / 2, height / 2 + 24);
|
||||
}
|
||||
|
||||
void calculateGame()
|
||||
{
|
||||
if (ball.position.x - ball.radius < lPaddle.position.x + lPaddle.size.width / 2)
|
||||
{
|
||||
if (ball.position.y < lPaddle.position.y - lPaddle.size.height / 2 - ball.radius||
|
||||
ball.position.y > lPaddle.position.y + lPaddle.size.height / 2 + ball.radius)
|
||||
{
|
||||
rScore++;
|
||||
ball.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
ball.speed.getSpeed();
|
||||
ball.speed.speed += acceleration;
|
||||
ball.speed.getXYSpeed((ball.position.y - lPaddle.position.y) / (lPaddle.size.height / 2) * deviate);
|
||||
}
|
||||
}
|
||||
|
||||
if (ball.position.x + ball.radius > rPaddle.position.x - rPaddle.size.width / 2)
|
||||
{
|
||||
if (ball.position.y < rPaddle.position.y - rPaddle.size.height / 2 - ball.radius||
|
||||
ball.position.y > rPaddle.position.y + rPaddle.size.height / 2 + ball.radius)
|
||||
{
|
||||
lScore++;
|
||||
ball.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
ball.speed.getSpeed();
|
||||
ball.speed.speed += acceleration;
|
||||
ball.speed.getXYSpeed((ball.position.y - rPaddle.position.y) / (rPaddle.size.height / 2) * deviate);
|
||||
ball.speed.x = - ball.speed.x;
|
||||
}
|
||||
}
|
||||
|
||||
if (lScore == winScore)
|
||||
gameState = GameState.PLAYER1WIN;
|
||||
if (rScore == winScore)
|
||||
gameState = GameState.PLAYER2WIN;
|
||||
}
|
||||
|
||||
void showGUI()
|
||||
{
|
||||
fill(255, 255, 255);
|
||||
textSize(16);
|
||||
textAlign(CENTER, CENTER);
|
||||
text("Press Enter to visit www.freenove.com", width / 4, height - 20);
|
||||
text("Press Space to restart game", width * 3 / 4, height - 20);
|
||||
text("Player 1: " + lScore, width / 4, 20);
|
||||
text("Player 2: " + rScore, width * 3 / 4, 20);
|
||||
|
||||
rectMode(CENTER);
|
||||
noStroke();
|
||||
fill(144, 144, 144);
|
||||
rect(width / 2, height / 2, 4, height);
|
||||
}
|
||||
|
||||
void keyPressed() {
|
||||
if (key == '\n' || key == '\r')
|
||||
{
|
||||
link("http://www.freenove.com");
|
||||
}
|
||||
else if (key == ' ')
|
||||
{
|
||||
lScore = 0;
|
||||
rScore = 0;
|
||||
ball.reset();
|
||||
gameState = GameState.PLAYING;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Class Ball
|
||||
* Author Ethan Pan @ Freenove (http://www.freenove.com)
|
||||
* Date 2016/7/22
|
||||
*******************************************************************************
|
||||
* Brief
|
||||
* This class is for pong game.
|
||||
*******************************************************************************
|
||||
* Copyright
|
||||
* Copyright © Freenove (http://www.freenove.com)
|
||||
* License
|
||||
* Creative Commons Attribution ShareAlike 3.0
|
||||
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Brief This class is for ball
|
||||
*****************************************************************************/
|
||||
class Ball {
|
||||
Point position = new Point();
|
||||
Speed speed = new Speed();
|
||||
int radius;
|
||||
float initialSpeed = 1;
|
||||
|
||||
Ball(int Radius)
|
||||
{
|
||||
radius = Radius;
|
||||
reset();
|
||||
}
|
||||
|
||||
void updata()
|
||||
{
|
||||
position.x += speed.x;
|
||||
position.y += speed.y;
|
||||
|
||||
if (position.y < radius || position.y > height - radius)
|
||||
speed.y = -speed.y;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
position.x = width / 2;
|
||||
position.y = height / 2;
|
||||
speed.x = (random(-1, 1) > 0 ? 1 : -1) * initialSpeed;
|
||||
speed.y = 0;
|
||||
}
|
||||
|
||||
void display()
|
||||
{
|
||||
ellipseMode(CENTER);
|
||||
noStroke();
|
||||
fill(255, 255, 255);
|
||||
ellipse(position.x, position.y, 2 * radius, 2 * radius);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Class BasicClass
|
||||
* Author Ethan Pan @ Freenove (http://www.freenove.com)
|
||||
* Date 2016/8/6
|
||||
*******************************************************************************
|
||||
* Brief
|
||||
* These basic classes are for pong game.
|
||||
*******************************************************************************
|
||||
* Copyright
|
||||
* Copyright © Freenove (http://www.freenove.com)
|
||||
* License
|
||||
* Creative Commons Attribution ShareAlike 3.0
|
||||
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Brief This class is used to save a point
|
||||
*****************************************************************************/
|
||||
class Point
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
|
||||
Point() {
|
||||
}
|
||||
|
||||
Point(float X, float Y)
|
||||
{
|
||||
x = X;
|
||||
y = Y;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Brief This class is used to save a size
|
||||
*****************************************************************************/
|
||||
class Size
|
||||
{
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
|
||||
Size() {
|
||||
}
|
||||
|
||||
Size(int Width, int Height)
|
||||
{
|
||||
width = Width;
|
||||
height = Height;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Brief This class is used to save a 2D speed
|
||||
*****************************************************************************/
|
||||
class Speed
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
float speed;
|
||||
|
||||
void getSpeed()
|
||||
{
|
||||
speed = sqrt(sq(x) + sq(y));
|
||||
}
|
||||
|
||||
void getXYSpeed(float degree)
|
||||
{
|
||||
x = speed * cos(degree);
|
||||
y = speed * sin(degree);
|
||||
}
|
||||
|
||||
Speed() {
|
||||
}
|
||||
|
||||
Speed(float X, float Y)
|
||||
{
|
||||
x = X;
|
||||
y = Y;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Brief This enum is used to save a gameState
|
||||
*****************************************************************************/
|
||||
class GameState
|
||||
{
|
||||
final static int WELCOME = 0;
|
||||
final static int PLAYING = 1;
|
||||
final static int PLAYER1WIN = 2;
|
||||
final static int PLAYER2WIN = 3;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*****************************************************
|
||||
* Filename : PCF8591
|
||||
* Description : class PCF8591,DAC and ADC
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/20
|
||||
*****************************************************/
|
||||
|
||||
class PCF8591 {
|
||||
private int address;
|
||||
private I2C i2c;
|
||||
//constructor,Parameters for the PCF8591 I2C address
|
||||
public PCF8591(int addr) {
|
||||
address = addr;
|
||||
i2c = new I2C(I2C.list()[0]);
|
||||
}
|
||||
//Read the ADC value of one channel
|
||||
public int analogRead(int chn) {
|
||||
int result = 0;
|
||||
i2c.beginTransmission(address);
|
||||
constrain(chn, 0, 3);
|
||||
i2c.write(0x40 | chn);
|
||||
try {
|
||||
byte[] in = i2c.read(1);
|
||||
result = in[0]&0xff;
|
||||
}
|
||||
catch(Exception e) {
|
||||
println(e);
|
||||
}
|
||||
i2c.endTransmission();
|
||||
return result;
|
||||
}
|
||||
//Read the ADC value of all channels
|
||||
public byte[] analogRead() {
|
||||
i2c.beginTransmission(address);
|
||||
i2c.write(0x44);
|
||||
i2c.endTransmission();
|
||||
byte[] in = i2c.read(4);
|
||||
return in;
|
||||
}
|
||||
//Write the DACvalue
|
||||
public void analogWrite(int data) {
|
||||
i2c.beginTransmission(address);
|
||||
i2c.write(0x40);
|
||||
i2c.write(data);
|
||||
i2c.endTransmission();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Class Paddle
|
||||
* Author Ethan Pan @ Freenove (http://www.freenove.com)
|
||||
* Date 2016/7/22
|
||||
*******************************************************************************
|
||||
* Brief
|
||||
* This class is for pong game.
|
||||
*******************************************************************************
|
||||
* Copyright
|
||||
* Copyright © Freenove (http://www.freenove.com)
|
||||
* License
|
||||
* Creative Commons Attribution ShareAlike 3.0
|
||||
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Brief This class is for paddle
|
||||
*****************************************************************************/
|
||||
class Paddle {
|
||||
Point position = new Point();
|
||||
Size size;
|
||||
|
||||
Paddle(Size paddleSize, int xPosition)
|
||||
{
|
||||
size = paddleSize;
|
||||
position.x = xPosition;
|
||||
position.y = height / 2;
|
||||
}
|
||||
|
||||
void moveTo(int yPosition)
|
||||
{
|
||||
position.y = yPosition;
|
||||
}
|
||||
|
||||
void display()
|
||||
{
|
||||
rectMode(CENTER);
|
||||
noStroke();
|
||||
fill(255, 255, 255);
|
||||
rect(position.x, position.y, size.width, size.height);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* Sketch App_04_1_1_Snake_Game
|
||||
* Author Freenove (http://www.freenove.com)
|
||||
* Date 2016/08/27
|
||||
******************************************************************************
|
||||
* Brief
|
||||
* This sketch is used to play snake game
|
||||
******************************************************************************
|
||||
* Copyright
|
||||
* Copyright © Freenove (http://www.freenove.com)
|
||||
* License
|
||||
* Creative Commons Attribution ShareAlike 3.0
|
||||
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
|
||||
******************************************************************************
|
||||
*/
|
||||
import processing.io.*;
|
||||
int threshold = 400;
|
||||
|
||||
KeyPad keyUp = new KeyPad(23);
|
||||
KeyPad keyDown = new KeyPad(17);
|
||||
KeyPad keyLeft = new KeyPad(22);
|
||||
KeyPad keyRight = new KeyPad(18);
|
||||
|
||||
Snake snake;
|
||||
Food food;
|
||||
|
||||
void setup() {
|
||||
print("Starting ... \n");
|
||||
size(640, 360);
|
||||
background(102);
|
||||
textAlign(CENTER, CENTER);
|
||||
textSize(64);
|
||||
text("Starting...", width / 2, (height - 40) / 2);
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20);
|
||||
|
||||
food = new Food(new GridMap(new Size(width, height), 20, 2));
|
||||
snake = new Snake(new GridMap(new Size(width, height), 20, 2));
|
||||
thread("keypadDetect");
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(102);
|
||||
if (snake.gameState == GameState.WELCOME)
|
||||
{
|
||||
rectMode(CENTER);
|
||||
stroke(0, 0, 0);
|
||||
fill(0, 0, 0, 50);
|
||||
rect(width / 2, height / 2, width / 2, height / 3);
|
||||
fill(255, 255, 255);
|
||||
textSize(24);
|
||||
textAlign(CENTER, CENTER);
|
||||
text("Snake Game", width / 2, height / 2 - 24);
|
||||
text("Press Space to start", width / 2, height / 2 + 24);
|
||||
} else if (snake.gameState == GameState.PLAYING)
|
||||
{
|
||||
|
||||
if (snake.body[0].x == food.position.x && snake.body[0].y == food.position.y)
|
||||
{
|
||||
snake.grow();
|
||||
food.generate(snake.body, snake.length);
|
||||
snake.speedUp();
|
||||
}
|
||||
snake.step();
|
||||
showGame();
|
||||
} else if (snake.gameState == GameState.LOSE)
|
||||
{
|
||||
showGame();
|
||||
rectMode(CENTER);
|
||||
stroke(0, 0, 0);
|
||||
fill(0, 0, 0, 50);
|
||||
rect(width / 2, height / 2, width / 2, height / 3);
|
||||
fill(255, 255, 255);
|
||||
textSize(24);
|
||||
textAlign(CENTER, CENTER);
|
||||
text("You lose!", width / 2, height / 2 - 24);
|
||||
text("Press Space to start", width / 2, height / 2 + 24);
|
||||
}
|
||||
}
|
||||
|
||||
void showGame()
|
||||
{
|
||||
snake.display();
|
||||
food.display();
|
||||
|
||||
fill(255, 255, 255);
|
||||
textSize(16);
|
||||
textAlign(LEFT, CENTER);
|
||||
text("Press Enter to visit www.freenove.com", 20, height - 20);
|
||||
textAlign(RIGHT, CENTER);
|
||||
text("Press Space to restart game", width - 20, height - 20);
|
||||
textAlign(LEFT, CENTER);
|
||||
text("Score: " + (snake.length - 3), 20, 20);
|
||||
textAlign(RIGHT, CENTER);
|
||||
text("Speed: " + ((snake.initSpeed - snake.speed) / 5 + 1), width - 20, 20);
|
||||
}
|
||||
|
||||
void keyPressed() {
|
||||
if ((key == CODED) || (keyValue != -1))
|
||||
{
|
||||
if ((keyCode == UP) ||((keyValue == keyUp.pin)))
|
||||
{
|
||||
if (snake.direction != Direction.DOWN)
|
||||
snake.nextDirection = Direction.UP;
|
||||
} else if ((keyCode == DOWN)||((keyValue == keyDown.pin))) {
|
||||
if (snake.direction != Direction.UP)
|
||||
snake.nextDirection = Direction.DOWN;
|
||||
} else if ((keyCode == LEFT)||((keyValue == keyLeft.pin))) {
|
||||
if (snake.direction != Direction.RIGHT)
|
||||
snake.nextDirection = Direction.LEFT;
|
||||
} else if ((keyCode == RIGHT)||((keyValue == keyRight.pin))) {
|
||||
if (snake.direction != Direction.LEFT)
|
||||
snake.nextDirection = Direction.RIGHT;
|
||||
}
|
||||
//keyValue = -1;
|
||||
println(keyValue);
|
||||
} else
|
||||
{
|
||||
if (key == '\n' || key == '\r')
|
||||
{
|
||||
link("http://www.freenove.com");
|
||||
} else if (key == ' ')
|
||||
{
|
||||
snake.reset();
|
||||
food.generate(snake.body, snake.length);
|
||||
snake.gameState = GameState.PLAYING;
|
||||
}
|
||||
}
|
||||
}
|
||||
void keypadDetect() {
|
||||
while (true) {
|
||||
keyUp.keyScan();
|
||||
keyDown.keyScan();
|
||||
keyLeft.keyScan();
|
||||
keyRight.keyScan();
|
||||
transAction();
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
}
|
||||
catch(Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
void transAction() {
|
||||
if ((keyValue != -1))
|
||||
{
|
||||
if (keyValue == keyUp.pin)
|
||||
{
|
||||
if (snake.direction != Direction.DOWN)
|
||||
snake.nextDirection = Direction.UP;
|
||||
} else if (((keyValue == keyDown.pin))) {
|
||||
if (snake.direction != Direction.UP)
|
||||
snake.nextDirection = Direction.DOWN;
|
||||
} else if (((keyValue == keyLeft.pin))) {
|
||||
if (snake.direction != Direction.RIGHT)
|
||||
snake.nextDirection = Direction.LEFT;
|
||||
} else if (((keyValue == keyRight.pin))) {
|
||||
if (snake.direction != Direction.LEFT)
|
||||
snake.nextDirection = Direction.RIGHT;
|
||||
}
|
||||
keyValue = -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Class BasicClass
|
||||
* Author Ethan Pan @ Freenove (http://www.freenove.com)
|
||||
* Date 2016/8/6
|
||||
*******************************************************************************
|
||||
* Brief
|
||||
* These basic classes are for snake game.
|
||||
*******************************************************************************
|
||||
* Copyright
|
||||
* Copyright © Freenove (http://www.freenove.com)
|
||||
* License
|
||||
* Creative Commons Attribution ShareAlike 3.0
|
||||
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Brief This class is used to save a point
|
||||
*****************************************************************************/
|
||||
class Point
|
||||
{
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
Point() {
|
||||
}
|
||||
|
||||
Point(int X, int Y)
|
||||
{
|
||||
x = X;
|
||||
y = Y;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Brief This class is used to save a size
|
||||
*****************************************************************************/
|
||||
class Size
|
||||
{
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
|
||||
Size() {
|
||||
}
|
||||
|
||||
Size(int Width, int Height)
|
||||
{
|
||||
width = Width;
|
||||
height = Height;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Brief This enum is used to save a direction
|
||||
*****************************************************************************/
|
||||
class Direction
|
||||
{
|
||||
final static int UP = 0;
|
||||
final static int DOWN = 1;
|
||||
final static int LEFT = 2;
|
||||
final static int RIGHT = 3;
|
||||
}
|
||||
|
||||
/*
|
||||
* Brief This enum is used to save a gameState
|
||||
*****************************************************************************/
|
||||
class GameState
|
||||
{
|
||||
final static int WELCOME = 0;
|
||||
final static int PLAYING = 1;
|
||||
final static int WIN = 2;
|
||||
final static int LOSE = 3;
|
||||
}
|
||||
|
||||
/*
|
||||
* Brief This enum is used to save a grid map
|
||||
*****************************************************************************/
|
||||
class GridMap
|
||||
{
|
||||
Size mapSize;
|
||||
Size gripSize;
|
||||
int gridLength;
|
||||
int blockGap;
|
||||
int blockLength;
|
||||
|
||||
GridMap() {
|
||||
}
|
||||
|
||||
GridMap(Size MapSize, int GridLength, int BlockGap)
|
||||
{
|
||||
mapSize = MapSize;
|
||||
gridLength = GridLength;
|
||||
gripSize = new Size(mapSize.width / gridLength, mapSize.height / gridLength);
|
||||
blockGap = BlockGap;
|
||||
blockLength = gridLength - blockGap;
|
||||
}
|
||||
|
||||
Point getGripPoint(Point mapPoint)
|
||||
{
|
||||
Point point = new Point();
|
||||
point.x = mapPoint.x / gridLength;
|
||||
point.y = mapPoint.y / gridLength;
|
||||
return point;
|
||||
}
|
||||
|
||||
Point getMapPoint(Point gripPoint)
|
||||
{
|
||||
Point point = new Point();
|
||||
point.x = gripPoint.x * gridLength + gridLength / 2;
|
||||
point.y = gripPoint.y * gridLength + gridLength / 2;
|
||||
return point;
|
||||
}
|
||||
|
||||
void adjustMapPoint(Point mapPoint)
|
||||
{
|
||||
mapPoint.x = mapPoint.x / gridLength * gridLength + gridLength / 2;
|
||||
mapPoint.y = mapPoint.y / gridLength * gridLength + gridLength / 2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Class Food
|
||||
* Author Ethan Pan @ Freenove (http://www.freenove.com)
|
||||
* Date 2016/7/20
|
||||
*******************************************************************************
|
||||
* Brief
|
||||
* This class is for snake game.
|
||||
*******************************************************************************
|
||||
* Copyright
|
||||
* Copyright © Freenove (http://www.freenove.com)
|
||||
* License
|
||||
* Creative Commons Attribution ShareAlike 3.0
|
||||
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Brief This class is for food
|
||||
*****************************************************************************/
|
||||
class Food {
|
||||
Point position;
|
||||
GridMap map;
|
||||
|
||||
Food(GridMap gridMap)
|
||||
{
|
||||
map = gridMap;
|
||||
}
|
||||
|
||||
void generate(Point[] exclude, int length)
|
||||
{
|
||||
Point point = new Point();
|
||||
boolean isGenerating = true;
|
||||
|
||||
while (isGenerating)
|
||||
{
|
||||
point.x = (int)random(0, map.gripSize.width - 1);
|
||||
point.y = (int)random(0, map.gripSize.height - 1);
|
||||
|
||||
isGenerating = false;
|
||||
if (exclude != null)
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
if (point.x == exclude[i].x && point.y == exclude[i].y)
|
||||
isGenerating = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
position = point;
|
||||
}
|
||||
|
||||
void display()
|
||||
{
|
||||
rectMode(CENTER);
|
||||
noStroke();
|
||||
fill(0, 255, 0);
|
||||
Point mapPosition = map.getMapPoint(position);
|
||||
rect(mapPosition.x, mapPosition.y, map.blockLength, map.blockLength);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* class Keypad
|
||||
* Author Freenove (http://www.freenove.com)
|
||||
* Date 2016/08/27
|
||||
******************************************************************************
|
||||
* Brief
|
||||
* This class is used to get a single button key value (GPIO numbering)
|
||||
******************************************************************************
|
||||
* Copyright
|
||||
* Copyright © Freenove (http://www.freenove.com)
|
||||
* License
|
||||
* Creative Commons Attribution ShareAlike 3.0
|
||||
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
|
||||
******************************************************************************
|
||||
*/
|
||||
int keyValue = -1;
|
||||
class KeyPad
|
||||
{
|
||||
final int IDLE = 0,
|
||||
PRESSED = 1,
|
||||
HOLD = 2,
|
||||
RELEASED = 3;
|
||||
int btnState = IDLE;
|
||||
long holdTimer = 0;
|
||||
final int holdTime = 500;
|
||||
boolean changeState = false;
|
||||
int lastButtonIOState = GPIO.HIGH;
|
||||
int buttonIOState=GPIO.HIGH;
|
||||
int nowButtonState;
|
||||
boolean buttonChanged = false;
|
||||
int lastChangeTime;
|
||||
int decounceTime = 50;
|
||||
int pin;
|
||||
public KeyPad(int Pin) {
|
||||
pin = Pin;
|
||||
GPIO.pinMode(pin, GPIO.INPUT);
|
||||
}
|
||||
|
||||
void keyScan() {
|
||||
nowButtonState =GPIO.digitalRead(pin);
|
||||
if (nowButtonState != lastButtonIOState) {
|
||||
lastChangeTime = millis();
|
||||
}
|
||||
if (millis() - lastChangeTime > decounceTime) {
|
||||
if (buttonIOState != nowButtonState) {
|
||||
buttonIOState = nowButtonState;
|
||||
changeState = true;
|
||||
if (buttonIOState == GPIO.LOW) {
|
||||
//btnState = PRESSED;
|
||||
//keyValue = pin;
|
||||
//println("Key is Pressed !! ");
|
||||
} else if (buttonIOState == GPIO.HIGH) {
|
||||
//println("Key is Released !! ");
|
||||
}
|
||||
}
|
||||
}
|
||||
switch(btnState) {
|
||||
case IDLE:
|
||||
if (changeState) {
|
||||
changeState = false;
|
||||
btnState = PRESSED;
|
||||
holdTimer = millis();
|
||||
keyValue = pin;
|
||||
}
|
||||
break;
|
||||
case PRESSED:
|
||||
if (millis() - holdTimer > holdTime) {
|
||||
btnState = HOLD;
|
||||
keyValue = pin;
|
||||
}else if(changeState){
|
||||
changeState = false;
|
||||
btnState = RELEASED;
|
||||
}
|
||||
break;
|
||||
case HOLD:
|
||||
keyValue = pin;
|
||||
if (changeState) {
|
||||
changeState = false;
|
||||
btnState = RELEASED;
|
||||
}
|
||||
break;
|
||||
case RELEASED:
|
||||
keyValue = -1;
|
||||
btnState = IDLE;
|
||||
break;
|
||||
}
|
||||
lastButtonIOState = nowButtonState;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Class Snake
|
||||
* Author Ethan Pan @ Freenove (http://www.freenove.com)
|
||||
* Date 2016/8/6
|
||||
*******************************************************************************
|
||||
* Brief
|
||||
* This class is for snake game.
|
||||
*******************************************************************************
|
||||
* Copyright
|
||||
* Copyright © Freenove (http://www.freenove.com)
|
||||
* License
|
||||
* Creative Commons Attribution ShareAlike 3.0
|
||||
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Brief This class is for snake
|
||||
*****************************************************************************/
|
||||
class Snake {
|
||||
GridMap map;
|
||||
|
||||
int length;
|
||||
final int initSpeed = 150;
|
||||
int speed;
|
||||
int stepCounter;
|
||||
int direction;
|
||||
int nextDirection;
|
||||
Point[] body;
|
||||
|
||||
int gameState = GameState.WELCOME;
|
||||
|
||||
Snake(GridMap gridMap)
|
||||
{
|
||||
map = gridMap;
|
||||
body = new Point[map.gripSize.height * map.gripSize.width];
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
length = 3;
|
||||
speed = initSpeed ;
|
||||
direction = Direction.UP;
|
||||
nextDirection = Direction.UP;
|
||||
body[0] = new Point(map.gripSize.width / 2, map.gripSize.height / 2);
|
||||
body[1] = new Point(body[0].x, body[0].y + 1);
|
||||
body[2] = new Point(body[0].x, body[0].y + 2);
|
||||
}
|
||||
|
||||
void display()
|
||||
{
|
||||
rectMode(CENTER);
|
||||
noStroke();
|
||||
fill(227, 118, 12);
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
Point mapPosition = map.getMapPoint(body[i]);
|
||||
rect(mapPosition.x, mapPosition.y, map.blockLength, map.blockLength);
|
||||
}
|
||||
}
|
||||
|
||||
void speedUp()
|
||||
{
|
||||
if (speed > 0)
|
||||
speed--;
|
||||
}
|
||||
|
||||
void grow()
|
||||
{
|
||||
length++;
|
||||
}
|
||||
|
||||
void step()
|
||||
{
|
||||
if (stepCounter++ % (speed / 5) != 0)
|
||||
return;
|
||||
|
||||
for (int i = length; i > 0; i--)
|
||||
body[i] = body[i - 1];
|
||||
|
||||
direction = nextDirection;
|
||||
if (direction == Direction.UP)
|
||||
{
|
||||
body[0] = new Point(body[1].x, body[1].y - 1);
|
||||
if (body[0].y < 0)
|
||||
gameState = GameState.LOSE;
|
||||
}
|
||||
else if (direction == Direction.DOWN)
|
||||
{
|
||||
body[0] = new Point(body[1].x, body[1].y + 1);
|
||||
if (body[0].y > map.gripSize.height - 1)
|
||||
gameState = GameState.LOSE;
|
||||
}
|
||||
else if (direction == Direction.LEFT)
|
||||
{
|
||||
body[0] = new Point(body[1].x - 1, body[1].y);
|
||||
if (body[0].x < 0)
|
||||
gameState = GameState.LOSE;
|
||||
}
|
||||
else if (direction == Direction.RIGHT)
|
||||
{
|
||||
body[0] = new Point(body[1].x + 1, body[1].y);
|
||||
if (body[0].x > map.gripSize.width - 1)
|
||||
gameState = GameState.LOSE;
|
||||
}
|
||||
|
||||
for (int i = 1; i < length; i++)
|
||||
{
|
||||
if (body[0].x == body[i].x && body[0].y == body[i].y)
|
||||
gameState = GameState.LOSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* Sketch App_05_1_1_Tetris
|
||||
* Author Freenove (http://www.freenove.com)
|
||||
* Date 2016/08/27
|
||||
******************************************************************************
|
||||
* Brief
|
||||
* This sketch is used to play Tetris game
|
||||
******************************************************************************
|
||||
* Copyright
|
||||
* Copyright © Freenove (http://www.freenove.com)
|
||||
* License
|
||||
* Creative Commons Attribution ShareAlike 3.0
|
||||
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
|
||||
******************************************************************************
|
||||
*/
|
||||
import processing.io.*;
|
||||
|
||||
static final int w = 10; // 4
|
||||
static final int h = 25; // 60
|
||||
static final int framesInSecond = 30;
|
||||
static float gameInitSpeed = 10;
|
||||
static float gameSpeed = 10;
|
||||
static final int BlockScale = 15;
|
||||
static final int sizeWidth = w*BlockScale+100;
|
||||
static final int sizeHeight = h*BlockScale;
|
||||
|
||||
|
||||
KeyPad keyUp = new KeyPad(23);
|
||||
KeyPad keyDown = new KeyPad(17);
|
||||
KeyPad keyLeft = new KeyPad(22);
|
||||
KeyPad keyRight = new KeyPad(18);
|
||||
|
||||
boolean isPaused = false;
|
||||
boolean keyAllow = true;
|
||||
float updatingThreshold = 0;
|
||||
Game game;
|
||||
|
||||
float recalculateUpdatingThreshold(float threshold) {
|
||||
return threshold + 1;
|
||||
}
|
||||
void settings() {
|
||||
size(sizeWidth, sizeHeight);
|
||||
}
|
||||
void setup() {
|
||||
game = new Game(w, h);
|
||||
generateRandomBlock(game);
|
||||
frameRate(framesInSecond);
|
||||
thread("keypadDetect");
|
||||
}
|
||||
|
||||
void draw() {
|
||||
|
||||
background(102);
|
||||
Game newGame = game;
|
||||
|
||||
updatingThreshold = recalculateUpdatingThreshold(updatingThreshold);
|
||||
if (updatingThreshold > gameSpeed) {
|
||||
if (isGameOver(newGame)) {
|
||||
} else if (isPaused) {
|
||||
} else {
|
||||
newGame = updateGameState(game);
|
||||
}
|
||||
updatingThreshold = 0;
|
||||
}
|
||||
drawGameState(newGame);
|
||||
if (!isGameOver(newGame)&& (isPaused)) { //pause
|
||||
textSize(40);
|
||||
fill(0);
|
||||
text("Pause", BlockScale*2, 150);
|
||||
keyAllow = false;
|
||||
} else if (isGameOver(newGame)&& (isPaused)) { //restart game
|
||||
game = new Game(w, h);
|
||||
generateRandomBlock(game);
|
||||
isPaused = false;
|
||||
keyAllow = false;
|
||||
} else if (isGameOver(newGame)) { //game over
|
||||
textSize(40);
|
||||
fill(0);
|
||||
text("Game \nOver", BlockScale*2, 150);
|
||||
keyAllow = false;
|
||||
} else { //playing
|
||||
keyAllow = true;
|
||||
}
|
||||
|
||||
//level,score information
|
||||
pushMatrix();
|
||||
translate(w*BlockScale, 0);
|
||||
fill(255);
|
||||
textSize(20);
|
||||
text("Level\n"+game.level, 10, BlockScale*7);
|
||||
text("Scores\n"+game.score, 10, BlockScale*11);
|
||||
textSize(12);
|
||||
text("Freenove.com", 10, sizeHeight-30);
|
||||
drawNextBlock(game.nextBlock, BlockScale*2, BlockScale*1);
|
||||
popMatrix();
|
||||
}
|
||||
|
||||
void keyPressed() {
|
||||
if (key == CODED) {
|
||||
if (keyAllow) {
|
||||
switch (keyCode) {
|
||||
case LEFT:
|
||||
moveBlock(game, MoveLeft);
|
||||
break;
|
||||
case RIGHT:
|
||||
moveBlock(game, MoveRight);
|
||||
break;
|
||||
case DOWN:
|
||||
makeBlockFall(game);
|
||||
break;
|
||||
case UP:
|
||||
rotateBlock(game);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (key == ' ') { // SPACE
|
||||
isPaused =! isPaused;
|
||||
}
|
||||
}
|
||||
void keypadDetect() {
|
||||
while (true) {
|
||||
keyUp.keyScan();
|
||||
keyDown.keyScan();
|
||||
keyLeft.keyScan();
|
||||
keyRight.keyScan();
|
||||
transAction();
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
}
|
||||
catch(Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
void transAction() {
|
||||
if ((keyValue != -1))
|
||||
{
|
||||
if (keyAllow) {
|
||||
if (keyValue == keyLeft.pin) {
|
||||
moveBlock(game, MoveLeft);
|
||||
} else if (keyValue == keyRight.pin) {
|
||||
moveBlock(game, MoveRight);
|
||||
} else if (keyValue == keyDown.pin) {
|
||||
makeBlockFall(game);
|
||||
} else if (keyValue == keyUp.pin) {
|
||||
rotateBlock(game);
|
||||
}
|
||||
}
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
}
|
||||
catch(Exception e) {
|
||||
}
|
||||
keyValue = -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* class Keypad
|
||||
* Author Freenove (http://www.freenove.com)
|
||||
* Date 2016/08/27
|
||||
******************************************************************************
|
||||
* Brief
|
||||
* This class is used to get a single button key value (GPIO numbering)
|
||||
******************************************************************************
|
||||
* Copyright
|
||||
* Copyright © Freenove (http://www.freenove.com)
|
||||
* License
|
||||
* Creative Commons Attribution ShareAlike 3.0
|
||||
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
|
||||
******************************************************************************
|
||||
*/
|
||||
int keyValue = -1;
|
||||
class KeyPad
|
||||
{
|
||||
final int IDLE = 0,
|
||||
PRESSED = 1,
|
||||
HOLD = 2,
|
||||
RELEASED = 3;
|
||||
int btnState = IDLE;
|
||||
long holdTimer = 0;
|
||||
final int holdTime = 500;
|
||||
boolean changeState = false;
|
||||
int lastButtonIOState = GPIO.HIGH;
|
||||
int buttonIOState=GPIO.HIGH;
|
||||
int nowButtonState;
|
||||
boolean buttonChanged = false;
|
||||
int lastChangeTime;
|
||||
int decounceTime = 50;
|
||||
int pin;
|
||||
public KeyPad(int Pin) {
|
||||
pin = Pin;
|
||||
GPIO.pinMode(pin, GPIO.INPUT);
|
||||
}
|
||||
|
||||
void keyScan() {
|
||||
nowButtonState =GPIO.digitalRead(pin);
|
||||
if (nowButtonState != lastButtonIOState) {
|
||||
lastChangeTime = millis();
|
||||
}
|
||||
if (millis() - lastChangeTime > decounceTime) {
|
||||
if (buttonIOState != nowButtonState) {
|
||||
buttonIOState = nowButtonState;
|
||||
changeState = true;
|
||||
if (buttonIOState == GPIO.LOW) {
|
||||
//btnState = PRESSED;
|
||||
//keyValue = pin;
|
||||
//println("Key is Pressed !! ");
|
||||
} else if (buttonIOState == GPIO.HIGH) {
|
||||
//println("Key is Released !! ");
|
||||
}
|
||||
}
|
||||
}
|
||||
switch(btnState) {
|
||||
case IDLE:
|
||||
if (changeState) {
|
||||
changeState = false;
|
||||
btnState = PRESSED;
|
||||
holdTimer = millis();
|
||||
keyValue = pin;
|
||||
}
|
||||
break;
|
||||
case PRESSED:
|
||||
if (millis() - holdTimer > holdTime) {
|
||||
btnState = HOLD;
|
||||
keyValue = pin;
|
||||
}else if(changeState){
|
||||
changeState = false;
|
||||
btnState = RELEASED;
|
||||
}
|
||||
break;
|
||||
case HOLD:
|
||||
keyValue = pin;
|
||||
if (changeState) {
|
||||
changeState = false;
|
||||
btnState = RELEASED;
|
||||
}
|
||||
break;
|
||||
case RELEASED:
|
||||
keyValue = -1;
|
||||
btnState = IDLE;
|
||||
break;
|
||||
}
|
||||
lastButtonIOState = nowButtonState;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// Classic Tetris only blocks
|
||||
static final int BlockPartsCount = 4;
|
||||
static final int BlocksCount = 7;
|
||||
static final int DirectionsCount = 4;
|
||||
|
||||
static final int I = 0;
|
||||
static final int O = 1;
|
||||
static final int T = 2;
|
||||
static final int S = 3;
|
||||
static final int Z = 4;
|
||||
static final int J = 5;
|
||||
static final int L = 6;
|
||||
|
||||
static final int North = 0;
|
||||
static final int East = 1;
|
||||
static final int South = 2;
|
||||
static final int West = 3;
|
||||
|
||||
class BlockPart {
|
||||
int xPos;
|
||||
int yPos;
|
||||
|
||||
BlockPart(int blockXPos, int blockYPos) {
|
||||
xPos = blockXPos;
|
||||
yPos = blockYPos;
|
||||
}
|
||||
};
|
||||
|
||||
class Block {
|
||||
int type;
|
||||
int xPos;
|
||||
int yPos;
|
||||
int direction;
|
||||
BlockPart[] parts;
|
||||
|
||||
Block (int blockType, int blockXPos, int blockYPos, int blockDirection) {
|
||||
type = blockType;
|
||||
xPos = blockXPos;
|
||||
yPos = blockYPos;
|
||||
direction = blockDirection;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,159 @@
|
||||
BlockPart[] getIBlockParts(int direction) {
|
||||
BlockPart[] parts = new BlockPart[BlockPartsCount];
|
||||
if ((direction == East) || (direction == West)) {
|
||||
parts[0] = new BlockPart(0,0);
|
||||
parts[1] = new BlockPart(1,0);
|
||||
parts[2] = new BlockPart(2,0);
|
||||
parts[3] = new BlockPart(3,0);
|
||||
} else {
|
||||
parts[0] = new BlockPart(0,0);
|
||||
parts[1] = new BlockPart(0,1);
|
||||
parts[2] = new BlockPart(0,2);
|
||||
parts[3] = new BlockPart(0,3);
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
BlockPart[] getOBlockParts() {
|
||||
BlockPart[] parts = new BlockPart[BlockPartsCount];
|
||||
parts[0] = new BlockPart(0,0);
|
||||
parts[1] = new BlockPart(1,0);
|
||||
parts[2] = new BlockPart(0,1);
|
||||
parts[3] = new BlockPart(1,1);
|
||||
return parts;
|
||||
}
|
||||
|
||||
BlockPart[] getTBlockParts(int direction) {
|
||||
BlockPart[] parts = new BlockPart[BlockPartsCount];
|
||||
switch (direction) {
|
||||
case East:
|
||||
parts[0] = new BlockPart(0,0);
|
||||
parts[1] = new BlockPart(1,0);
|
||||
parts[2] = new BlockPart(2,0);
|
||||
parts[3] = new BlockPart(1,1);
|
||||
break;
|
||||
case South:
|
||||
parts[0] = new BlockPart(1,0);
|
||||
parts[1] = new BlockPart(0,1);
|
||||
parts[2] = new BlockPart(1,1);
|
||||
parts[3] = new BlockPart(1,2);
|
||||
break;
|
||||
case West:
|
||||
parts[0] = new BlockPart(1,0);
|
||||
parts[1] = new BlockPart(0,1);
|
||||
parts[2] = new BlockPart(1,1);
|
||||
parts[3] = new BlockPart(2,1);
|
||||
break;
|
||||
case North:
|
||||
parts[0] = new BlockPart(0,0);
|
||||
parts[1] = new BlockPart(0,1);
|
||||
parts[2] = new BlockPart(1,1);
|
||||
parts[3] = new BlockPart(0,2);
|
||||
break;
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
BlockPart[] getSBlockParts(int direction) {
|
||||
BlockPart[] parts = new BlockPart[BlockPartsCount];
|
||||
switch (direction) {
|
||||
case East:
|
||||
case West:
|
||||
parts[0] = new BlockPart(0,0);
|
||||
parts[1] = new BlockPart(0,1);
|
||||
parts[2] = new BlockPart(1,1);
|
||||
parts[3] = new BlockPart(1,2);
|
||||
break;
|
||||
case South:
|
||||
case North:
|
||||
parts[0] = new BlockPart(0,1);
|
||||
parts[1] = new BlockPart(1,0);
|
||||
parts[2] = new BlockPart(1,1);
|
||||
parts[3] = new BlockPart(2,0);
|
||||
break;
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
BlockPart[] getZBlockParts(int direction) {
|
||||
BlockPart[] parts = new BlockPart[BlockPartsCount];
|
||||
switch (direction) {
|
||||
case East:
|
||||
case West:
|
||||
parts[0] = new BlockPart(1,0);
|
||||
parts[1] = new BlockPart(0,1);
|
||||
parts[2] = new BlockPart(1,1);
|
||||
parts[3] = new BlockPart(0,2);
|
||||
break;
|
||||
case South:
|
||||
case North:
|
||||
parts[0] = new BlockPart(0,0);
|
||||
parts[1] = new BlockPart(1,0);
|
||||
parts[2] = new BlockPart(1,1);
|
||||
parts[3] = new BlockPart(2,1);
|
||||
break;
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
BlockPart[] getJBlockParts(int direction) {
|
||||
BlockPart[] parts = new BlockPart[BlockPartsCount];
|
||||
switch (direction) {
|
||||
case East:
|
||||
parts[0] = new BlockPart(1,0);
|
||||
parts[1] = new BlockPart(1,1);
|
||||
parts[2] = new BlockPart(0,2);
|
||||
parts[3] = new BlockPart(1,2);
|
||||
break;
|
||||
case South:
|
||||
parts[0] = new BlockPart(0,0);
|
||||
parts[1] = new BlockPart(0,1);
|
||||
parts[2] = new BlockPart(1,1);
|
||||
parts[3] = new BlockPart(2,1);
|
||||
break;
|
||||
case West:
|
||||
parts[0] = new BlockPart(0,0);
|
||||
parts[1] = new BlockPart(1,0);
|
||||
parts[2] = new BlockPart(0,1);
|
||||
parts[3] = new BlockPart(0,2);
|
||||
break;
|
||||
case North:
|
||||
parts[0] = new BlockPart(0,0);
|
||||
parts[1] = new BlockPart(1,0);
|
||||
parts[2] = new BlockPart(2,0);
|
||||
parts[3] = new BlockPart(2,1);
|
||||
break;
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
BlockPart[] getLBlockParts(int direction) {
|
||||
BlockPart[] parts = new BlockPart[BlockPartsCount];
|
||||
switch (direction) {
|
||||
case East:
|
||||
parts[0] = new BlockPart(0,0);
|
||||
parts[1] = new BlockPart(0,1);
|
||||
parts[2] = new BlockPart(0,2);
|
||||
parts[3] = new BlockPart(1,2);
|
||||
break;
|
||||
case South:
|
||||
parts[0] = new BlockPart(0,0);
|
||||
parts[1] = new BlockPart(0,1);
|
||||
parts[2] = new BlockPart(1,0);
|
||||
parts[3] = new BlockPart(2,0);
|
||||
break;
|
||||
case West:
|
||||
parts[0] = new BlockPart(0,0);
|
||||
parts[1] = new BlockPart(1,0);
|
||||
parts[2] = new BlockPart(1,1);
|
||||
parts[3] = new BlockPart(1,2);
|
||||
break;
|
||||
case North:
|
||||
parts[0] = new BlockPart(0,1);
|
||||
parts[1] = new BlockPart(1,1);
|
||||
parts[2] = new BlockPart(2,0);
|
||||
parts[3] = new BlockPart(2,1);
|
||||
break;
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
|
||||
|
||||
BlockPart[] getBlockParts(Block block) {
|
||||
switch(block.type) {
|
||||
case I: return getIBlockParts(block.direction);
|
||||
case O: return getOBlockParts();
|
||||
case T: return getTBlockParts(block.direction);
|
||||
case S: return getSBlockParts(block.direction);
|
||||
case Z: return getZBlockParts(block.direction);
|
||||
case J: return getJBlockParts(block.direction);
|
||||
case L: return getLBlockParts(block.direction);
|
||||
}
|
||||
|
||||
return getIBlockParts(block.direction);
|
||||
}
|
||||
|
||||
void makeBlockFall(Block block) {
|
||||
block.yPos += 1;
|
||||
for (int i = 0; i < BlockPartsCount; i++) {
|
||||
block.parts[i].yPos += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// We assume, only unsigned int is possible in block parts[i].xPos.
|
||||
void arrangeNewBlock(Block block, int wellWidth) {
|
||||
|
||||
int leftXShift = 0;
|
||||
int maxYShift = 0;
|
||||
for (int i = 0; i < BlockPartsCount; i++) {
|
||||
|
||||
maxYShift = max (block.parts[i].yPos, maxYShift);
|
||||
|
||||
block.parts[i].xPos = block.parts[i].xPos + block.xPos;
|
||||
block.parts[i].yPos = block.parts[i].yPos + block.yPos;
|
||||
|
||||
if (block.parts[i].xPos >= wellWidth)
|
||||
leftXShift = max(leftXShift, block.parts[i].xPos + 1 - wellWidth);
|
||||
}
|
||||
|
||||
for (int i = 0; i < BlockPartsCount; i++) {
|
||||
block.parts[i].xPos = block.parts[i].xPos - leftXShift;
|
||||
block.parts[i].yPos = block.parts[i].yPos - (1 + maxYShift);
|
||||
}
|
||||
}
|
||||
|
||||
Block createBlock(int type, int direction, int xPos, int yPos, int wellWidth) {
|
||||
Block block = new Block(type, xPos, yPos, direction);
|
||||
block.parts = getBlockParts(block);
|
||||
arrangeNewBlock(block, wellWidth);
|
||||
return block;
|
||||
}
|
||||
|
||||
void moveBlockHorizontal(Block block, int distance) {
|
||||
for (int i = 0; i < BlockPartsCount; i++) {
|
||||
block.parts[i].xPos = block.parts[i].xPos + distance;
|
||||
}
|
||||
block.xPos += distance;
|
||||
}
|
||||
|
||||
int rotateDirection(int prevDirection) {
|
||||
if (prevDirection < DirectionsCount - 1)
|
||||
return prevDirection + 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
class Game {
|
||||
int wellWidth;
|
||||
int wellHeight;
|
||||
int score;
|
||||
int level;
|
||||
boolean[][] blocks;
|
||||
Block fallingBlock;
|
||||
Block nextBlock;
|
||||
boolean erasingNeeded;
|
||||
|
||||
Game (int w, int h) {
|
||||
wellWidth = w;
|
||||
wellHeight = h;
|
||||
fallingBlock = null;
|
||||
erasingNeeded = false;
|
||||
|
||||
blocks = new boolean[w][h];
|
||||
for (int x = 0; x < w; x++)
|
||||
for (int y = 0; y < h; y++)
|
||||
blocks[x][y] = false;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,160 @@
|
||||
static final int MoveLeft = -1;
|
||||
static final int MoveRight = 1;
|
||||
|
||||
boolean isBlockStuck(Game game)
|
||||
{
|
||||
Block block = game.fallingBlock;
|
||||
if (block == null)
|
||||
return false;
|
||||
|
||||
boolean[][] blocks = game.blocks;
|
||||
BlockPart[] parts = block.parts;
|
||||
|
||||
boolean stuck = false;
|
||||
for (int i = 0; (i < BlockPartsCount) && (!stuck); i++) {
|
||||
if (parts[i].xPos >= 0 && parts[i].yPos >= 0)
|
||||
stuck = stuck
|
||||
|| parts[i].yPos + 1 >= game.wellHeight
|
||||
|| blocks[parts[i].xPos][parts[i].yPos + 1];
|
||||
}
|
||||
|
||||
return stuck;
|
||||
}
|
||||
|
||||
void fixateBlock(Game game) {
|
||||
Block block = game.fallingBlock;
|
||||
if (block == null)
|
||||
return;
|
||||
|
||||
BlockPart[] parts = block.parts;
|
||||
|
||||
for (int i = 0; i < BlockPartsCount; i++) {
|
||||
if (parts[i].yPos >= 0)
|
||||
game.blocks[parts[i].xPos][parts[i].yPos] = true;
|
||||
}
|
||||
|
||||
game.fallingBlock = null;
|
||||
}
|
||||
|
||||
void eraseFilledLines(Game game) {
|
||||
int eraseRows=0;
|
||||
for (int y = game.wellHeight - 1; y >= 0; ) {
|
||||
|
||||
boolean erasable = true;
|
||||
for (int x = 0; x < game.wellWidth; x++)
|
||||
erasable = erasable && game.blocks[x][y];
|
||||
|
||||
if (erasable) {
|
||||
eraseRows +=1;
|
||||
// Move blocks down
|
||||
for (int y2 = y - 1; y2 >= 0; y2--)
|
||||
for (int x = 0; x < game.wellWidth; x++)
|
||||
game.blocks[x][y2 + 1] = game.blocks[x][y2];
|
||||
|
||||
// Top level needs to be cleared.
|
||||
for (int x = 0; x < game.wellWidth; x++)
|
||||
game.blocks[x][0] = false;
|
||||
} else {
|
||||
y--;
|
||||
}
|
||||
}
|
||||
if (eraseRows != 0) {
|
||||
game.score+=10*(eraseRows*2-1);
|
||||
eraseRows=0;
|
||||
game.level = game.score / 200;
|
||||
if (game.level <0) {
|
||||
game.level = 0;
|
||||
} else if (game.level > 9) {
|
||||
game.level = 9;
|
||||
}
|
||||
gameSpeed = (gameInitSpeed-game.level);
|
||||
}
|
||||
game.erasingNeeded = false;
|
||||
}
|
||||
|
||||
void enableErasing(Game game) {
|
||||
game.erasingNeeded = true;
|
||||
}
|
||||
|
||||
Block randomBlock() {
|
||||
int blockType = int(random(0, BlocksCount));
|
||||
int blockDirection = int(random(0, DirectionsCount));
|
||||
Block block = new Block(blockType, 0, 0, blockDirection);
|
||||
block.parts = getBlockParts(block);
|
||||
return block;
|
||||
}
|
||||
|
||||
void generateRandomBlock(Game game) {
|
||||
int blockType = int(random(0, BlocksCount));
|
||||
int blockDirection = int(random(0, DirectionsCount));
|
||||
//int xPos = int(random(0, game.wellWidth));
|
||||
int xPos = game.wellWidth/2-1;
|
||||
//game.fallingBlock = createBlock(blockType, blockDirection, xPos, -1, game.wellWidth);
|
||||
if (game.nextBlock == null) {
|
||||
game.fallingBlock = createBlock(blockType, blockDirection, xPos, -1, game.wellWidth);
|
||||
game.nextBlock = randomBlock();
|
||||
} else {
|
||||
game.fallingBlock = game.nextBlock;
|
||||
game.fallingBlock.xPos = game.wellWidth/2-1;
|
||||
arrangeNewBlock(game.fallingBlock, game.wellWidth);
|
||||
game.nextBlock = randomBlock();
|
||||
}
|
||||
}
|
||||
|
||||
boolean isBlockMovingPossible(Game game, int moveDirection) {
|
||||
Block block = game.fallingBlock;
|
||||
if (block == null)
|
||||
return false;
|
||||
|
||||
boolean possible = true;
|
||||
for (int i = 0; i < BlockPartsCount; i++) {
|
||||
|
||||
int desiredXPos = block.parts[i].xPos + moveDirection;
|
||||
int desiredYPos = block.parts[i].yPos;
|
||||
|
||||
possible = possible
|
||||
&& (moveDirection == MoveLeft ? desiredXPos >= 0 : desiredXPos < game.wellWidth);
|
||||
|
||||
if ((desiredYPos >= 0) && (desiredYPos < game.wellHeight))
|
||||
possible = possible && !(game.blocks[desiredXPos][desiredYPos]);
|
||||
}
|
||||
return possible;
|
||||
}
|
||||
|
||||
void moveBlock(Game game, int moveDirection) {
|
||||
if (isBlockMovingPossible(game, moveDirection))
|
||||
moveBlockHorizontal(game.fallingBlock, moveDirection);
|
||||
}
|
||||
|
||||
void makeBlockFall(Game game) {
|
||||
if (isBlockStuck(game)) {
|
||||
fixateBlock(game);
|
||||
enableErasing(game);
|
||||
generateRandomBlock(game);
|
||||
} else {
|
||||
makeBlockFall(game.fallingBlock);
|
||||
}
|
||||
}
|
||||
|
||||
void rotateBlock(Game game) {
|
||||
Block block = game.fallingBlock;
|
||||
Block rotated = createBlock(block.type, rotateDirection(block.direction), block.xPos, block.yPos, game.wellWidth);
|
||||
game.fallingBlock = rotated;
|
||||
}
|
||||
|
||||
Game updateGameState(Game game) {
|
||||
Game currentGame = game;
|
||||
if (currentGame.erasingNeeded) {
|
||||
eraseFilledLines(currentGame);
|
||||
} else if (currentGame.fallingBlock != null) {
|
||||
makeBlockFall(currentGame);
|
||||
}
|
||||
return currentGame;
|
||||
}
|
||||
|
||||
boolean isGameOver(Game game) {
|
||||
for (int i = 0; i < game.wellWidth; i++)
|
||||
if (game.blocks[i][0])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
|
||||
|
||||
void drawWellGrid(int w, int h)
|
||||
{
|
||||
for (int x = 0; x < w; x++) {
|
||||
for (int y = 0; y < h; y++) {
|
||||
stroke(0xFFBBBB00);
|
||||
fill(0xFF00FF00);
|
||||
rect(x*BlockScale, y*BlockScale, BlockScale, BlockScale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawBlocks(int w, int h, boolean[][] blocks) {
|
||||
for (int x = 0; x < w; x++) {
|
||||
for (int y = 0; y < h; y++) {
|
||||
if (blocks[x][y]) {
|
||||
//fill(0xFF000000 | (int)random(0xFFFFFF)); // For fun.
|
||||
fill(0xFF0000FF);
|
||||
rect(x*BlockScale, y*BlockScale, BlockScale, BlockScale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawFallingBlock(Block block)
|
||||
{
|
||||
if (block == null)
|
||||
return;
|
||||
|
||||
BlockPart[] parts = block.parts;
|
||||
|
||||
stroke(0x00BB0000);
|
||||
fill(0xFFFF0000);
|
||||
|
||||
for (int i = 0; i < BlockPartsCount; i++)
|
||||
rect(parts[i].xPos*BlockScale, parts[i].yPos*BlockScale, BlockScale, BlockScale);
|
||||
}
|
||||
|
||||
void drawNextBlock(Block block,int x,int y) {
|
||||
if (block == null)
|
||||
return;
|
||||
|
||||
BlockPart[] parts = block.parts;
|
||||
stroke(255,0,0);
|
||||
fill(255,255,0);
|
||||
for (int i = 0; i < BlockPartsCount; i++)
|
||||
rect(parts[i].xPos*BlockScale+x, parts[i].yPos*BlockScale+y, BlockScale, BlockScale);
|
||||
}
|
||||
|
||||
void drawGameState(Game game)
|
||||
{
|
||||
drawWellGrid(game.wellWidth, game.wellHeight);
|
||||
drawBlocks(game.wellWidth, game.wellHeight, game.blocks);
|
||||
drawFallingBlock(game.fallingBlock);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*****************************************************
|
||||
* Filename : Sketch_01_1_1_Blink
|
||||
* Description : Make an led blinking.
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/14
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
int ledPin = 17; //define ledPin
|
||||
boolean ledState = false; //define ledState
|
||||
|
||||
void setup() {
|
||||
size(100, 100);
|
||||
frameRate(1); //set frame rate
|
||||
GPIO.pinMode(ledPin, GPIO.OUTPUT); //set the ledPin to output mode
|
||||
}
|
||||
|
||||
void draw() {
|
||||
ledState = !ledState;
|
||||
if (ledState) {
|
||||
GPIO.digitalWrite(ledPin, GPIO.HIGH); //led on
|
||||
background(255, 0, 0); //set the fill color of led on
|
||||
} else {
|
||||
GPIO.digitalWrite(ledPin, GPIO.LOW); //led off
|
||||
background(102); //set the fill color of led off
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*****************************************************
|
||||
* Filename : Sketch_01_2_1_MouseLED
|
||||
* Description : Use the mouse to control the LED ON OFF
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/14
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
int ledPin = 17;
|
||||
boolean ledState = false;
|
||||
void setup() {
|
||||
size(100, 100);
|
||||
GPIO.pinMode(ledPin, GPIO.OUTPUT);
|
||||
background(102);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
if (ledState) {
|
||||
GPIO.digitalWrite(ledPin, GPIO.HIGH);
|
||||
background(255,0,0);
|
||||
} else {
|
||||
GPIO.digitalWrite(ledPin, GPIO.LOW);
|
||||
background(102);
|
||||
}
|
||||
}
|
||||
|
||||
void mouseClicked() { //if the mouse Clicked
|
||||
ledState = !ledState; //Change the led State
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*****************************************************
|
||||
* Filename : Sketch_02_1_1_FollowLight
|
||||
* Description : Use the mouse to control the LEDGraph Bar
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/15
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
int leds[]={17, 18, 27, 22, 23, 24, 25, 2, 3, 8}; //define ledPins
|
||||
|
||||
void setup() {
|
||||
size(640, 360); //display window size
|
||||
for (int i=0; i<10; i++) { //set led Pins to output mode
|
||||
GPIO.pinMode(leds[i], GPIO.OUTPUT);
|
||||
}
|
||||
background(102);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textSize(40); //set text size
|
||||
text("Follow Light", width / 2, 40); //title
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20); //site
|
||||
}
|
||||
|
||||
void draw() {
|
||||
for (int i=0; i<10; i++) { //draw 10 rectanglar box
|
||||
if (mouseX>(25+60*i)) { //if the mouse cursor on the right of rectanglar box
|
||||
fill(255, 0, 0); //fill the rectanglar box in red color
|
||||
GPIO.digitalWrite(leds[i], GPIO.LOW); //turn on the corresponding led
|
||||
} else {
|
||||
fill(255, 255, 255); //else fill the rectanglar box in white color and turn off the led
|
||||
GPIO.digitalWrite(leds[i], GPIO.HIGH);
|
||||
}
|
||||
rect(25+60*i, 90, 50, 180); //draw a rectanglar box
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import processing.io.*;
|
||||
|
||||
class SOFTPWM {
|
||||
public int pin=-1;
|
||||
public long range = -1;
|
||||
private Thread t = new Thread(new myThread());
|
||||
//private Thread t = new Thread();
|
||||
public long marks = 0; //high level time of period
|
||||
public long space = 0; //low level time of period
|
||||
public SOFTPWM(int iPin, int dc, int pwmRange) {
|
||||
pin = iPin;
|
||||
range = pwmRange*100000; //unit : 0.1ms
|
||||
marks = dc*100000;
|
||||
GPIO.pinMode(pin, GPIO.OUTPUT);
|
||||
t.start();
|
||||
}
|
||||
public void softPwmWrite(int value) {
|
||||
value *= 100000;
|
||||
constrain(value, 0, range);
|
||||
marks = value;
|
||||
}
|
||||
public void softPwmStop() {
|
||||
t.stop();
|
||||
GPIO.digitalWrite(pin, GPIO.LOW);
|
||||
}
|
||||
private class myThread implements Runnable {
|
||||
public void run() {
|
||||
while (true) {
|
||||
space = range - marks;
|
||||
if (marks !=0 ) {
|
||||
GPIO.digitalWrite(pin, GPIO.HIGH);
|
||||
delayMicroSeconds(marks);
|
||||
}
|
||||
if (space !=0 ) {
|
||||
GPIO.digitalWrite(pin, GPIO.LOW);
|
||||
delayMicroSeconds(space);
|
||||
}
|
||||
//println("mark : "+marks+" space : "+space);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SEC {
|
||||
public long msec;
|
||||
public int nsec;
|
||||
}
|
||||
void delayMicroSeconds(long howlong) {
|
||||
SEC s = new SEC();
|
||||
s.msec = howlong / 1000000;
|
||||
s.nsec = (int)howlong % 1000000;
|
||||
try {
|
||||
Thread.sleep(s.msec, s.nsec);
|
||||
}
|
||||
catch(Exception e) {
|
||||
println(e);
|
||||
println("msec: "+s.msec+" nsec: "+s.nsec);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*****************************************************
|
||||
* Filename : Sketch_03_1_1_BreathingLED
|
||||
* Description : Using PWM control LED brightness
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/18
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
int ledPin = 17; //led Pin
|
||||
int borderSize = 40; //
|
||||
float t = 0.0; //progress percent
|
||||
float tStep = 0.004; // speed
|
||||
SOFTPWM p = new SOFTPWM(ledPin, 10, 100); //Create a PWM pin,initialize the duty cycle and period
|
||||
void setup() {
|
||||
size(640, 360); //display window size
|
||||
strokeWeight(4); //stroke Weight
|
||||
}
|
||||
|
||||
void draw() {
|
||||
// Show static value when mouse is pressed, animate otherwise
|
||||
if (mousePressed) {
|
||||
int a = constrain(mouseX, borderSize, width - borderSize);
|
||||
t = map(a, borderSize, width - borderSize, 0.0, 1.0);
|
||||
} else {
|
||||
t += tStep;
|
||||
if (t > 1.0) t = 0.0;
|
||||
}
|
||||
p.softPwmWrite((int)(t*100)); //wirte the duty cycle according to t
|
||||
background(255); //A white background
|
||||
titleAndSiteInfo(); //title and Site infomation
|
||||
|
||||
fill(255, 255-t*255, 255-t*255); //cycle
|
||||
ellipse(width/2, height/2, 100, 100);
|
||||
|
||||
pushMatrix();
|
||||
translate(borderSize, height - 45);
|
||||
int barLength = width - 2*borderSize;
|
||||
|
||||
barBgStyle(); //progressbar bg
|
||||
line(0, 0, barLength, 0);
|
||||
line(barLength, -5, barLength, 5);
|
||||
|
||||
barStyle(); //progressbar
|
||||
line(0, -5, 0, 5);
|
||||
line(0, 0, t*barLength, 0);
|
||||
|
||||
barLabelStyle(); //progressbar label
|
||||
text("progress : "+nf(t*100,2,2),barLength/2,-25);
|
||||
popMatrix();
|
||||
}
|
||||
|
||||
void titleAndSiteInfo() {
|
||||
fill(0);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textSize(40); //set text size
|
||||
text("Breathing Light", width / 2, 40); //title
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20); //site
|
||||
}
|
||||
void barBgStyle() {
|
||||
stroke(220);
|
||||
noFill();
|
||||
}
|
||||
|
||||
void barStyle() {
|
||||
stroke(50);
|
||||
noFill();
|
||||
}
|
||||
|
||||
void barLabelStyle() {
|
||||
noStroke();
|
||||
fill(120);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
|
||||
|
||||
class ProgressBar {
|
||||
|
||||
int x, y;
|
||||
int barLength;
|
||||
float progress;
|
||||
String title;
|
||||
public ProgressBar(int ix, int iy, int barlen) {
|
||||
x = ix;
|
||||
y = iy;
|
||||
barLength = barlen;
|
||||
progress = 0;
|
||||
title = "Progress";
|
||||
}
|
||||
public void setTitle(String str){
|
||||
title = str;
|
||||
}
|
||||
public void setProgress(float pgress) {
|
||||
constrain(pgress, 0, 1.0);
|
||||
progress = pgress;
|
||||
}
|
||||
public void create() {
|
||||
pushMatrix();
|
||||
translate(x, y);
|
||||
textAlign(CENTER);
|
||||
textSize(16);
|
||||
barBgStyle(); //progressbar bg
|
||||
line(0, 0, barLength, 0);
|
||||
line(barLength, -5, barLength, 5);
|
||||
|
||||
barStyle(); //progressbar
|
||||
line(0, -5, 0, 5);
|
||||
line(0, 0, progress*barLength, 0);
|
||||
|
||||
barLabelStyle(); //progressbar label
|
||||
text(title+" : "+nf(progress*100, 2, 2)+"%", barLength/2, -5);
|
||||
popMatrix();
|
||||
}
|
||||
public void create(float pgress) {
|
||||
setProgress(pgress);
|
||||
pushMatrix();
|
||||
translate(x, y);
|
||||
|
||||
barBgStyle(); //progressbar bg
|
||||
line(0, 0, barLength, 0);
|
||||
line(barLength, -5, barLength, 5);
|
||||
|
||||
barStyle(); //progressbar
|
||||
line(0, -5, 0, 5);
|
||||
line(0, 0, progress*barLength, 0);
|
||||
|
||||
barLabelStyle(); //progressbar label
|
||||
text(title+" : "+nf(progress*100, 2, 2)+"%", barLength/2, -5);
|
||||
popMatrix();
|
||||
}
|
||||
void barBgStyle() {
|
||||
stroke(220);
|
||||
noFill();
|
||||
}
|
||||
|
||||
void barStyle() {
|
||||
stroke(50);
|
||||
noFill();
|
||||
}
|
||||
|
||||
void barLabelStyle() {
|
||||
noStroke();
|
||||
fill(120);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import processing.io.*;
|
||||
|
||||
class SOFTPWM {
|
||||
public int pin=-1;
|
||||
public long range = -1;
|
||||
private Thread t = new Thread(new myThread());
|
||||
//private Thread t = new Thread();
|
||||
public long marks = 0; //high level time of period
|
||||
public long space = 0; //low level time of period
|
||||
public SOFTPWM(int iPin, int dc, int pwmRange) {
|
||||
pin = iPin;
|
||||
range = pwmRange*100000; //unit : 0.1ms
|
||||
marks = dc*100000;
|
||||
GPIO.pinMode(pin, GPIO.OUTPUT);
|
||||
t.start();
|
||||
}
|
||||
public void softPwmWrite(int value) {
|
||||
value *= 100000;
|
||||
constrain(value, 0, range);
|
||||
marks = value;
|
||||
}
|
||||
public void softPwmStop() {
|
||||
t.stop();
|
||||
GPIO.digitalWrite(pin, GPIO.LOW);
|
||||
}
|
||||
private class myThread implements Runnable {
|
||||
public void run() {
|
||||
while (true) {
|
||||
space = range - marks;
|
||||
if (marks !=0 ) {
|
||||
GPIO.digitalWrite(pin, GPIO.HIGH);
|
||||
delayMicroSeconds(marks);
|
||||
}
|
||||
if (space !=0 ) {
|
||||
GPIO.digitalWrite(pin, GPIO.LOW);
|
||||
delayMicroSeconds(space);
|
||||
}
|
||||
//println("mark : "+marks+" space : "+space);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SEC {
|
||||
public long msec;
|
||||
public int nsec;
|
||||
}
|
||||
void delayMicroSeconds(long howlong) {
|
||||
SEC s = new SEC();
|
||||
s.msec = howlong / 1000000;
|
||||
s.nsec = (int)howlong % 1000000;
|
||||
try {
|
||||
Thread.sleep(s.msec, s.nsec);
|
||||
}
|
||||
catch(Exception e) {
|
||||
println(e);
|
||||
println("msec: "+s.msec+" nsec: "+s.nsec);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*****************************************************
|
||||
* Filename : Sketch_04_1_1_ColorfulLED
|
||||
* Description : Using slider controlRGBLED
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/20
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
int bluePin = 17; //blue Pin
|
||||
int greenPin = 27; //green Pin
|
||||
int redPin = 22; //red Pin
|
||||
int borderSize = 40; //picture border size
|
||||
//Create a PWM pin,initialize the duty cycle and period
|
||||
SOFTPWM pRed = new SOFTPWM(redPin, 100, 100);
|
||||
SOFTPWM pGreen = new SOFTPWM(greenPin, 100, 100);
|
||||
SOFTPWM pBlue = new SOFTPWM(bluePin, 100, 100);
|
||||
//instantiate three ProgressBar Object
|
||||
ProgressBar rBar, gBar, bBar;
|
||||
boolean rMouse = false, gMouse = false, bMouse = false;
|
||||
void setup() {
|
||||
size(640, 360); //display window size
|
||||
strokeWeight(4); //stroke Weight
|
||||
//define the ProgressBar length
|
||||
int barLength = width - 2*borderSize;
|
||||
//Create ProgressBar Object
|
||||
rBar = new ProgressBar(borderSize, height - 85, barLength);
|
||||
gBar = new ProgressBar(borderSize, height - 65, barLength);
|
||||
bBar = new ProgressBar(borderSize, height - 45, barLength);
|
||||
//Set ProgressBar's title
|
||||
rBar.setTitle("Red");gBar.setTitle("Green");bBar.setTitle("Blue");
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(200); //A white background
|
||||
titleAndSiteInfo(); //title and Site infomation
|
||||
|
||||
fill(rBar.progress*255, gBar.progress*255, bBar.progress*255); //cycle color
|
||||
ellipse(width/2, height/2, 100, 100); //show cycle
|
||||
|
||||
rBar.create(); //Show progressBar
|
||||
gBar.create();
|
||||
bBar.create();
|
||||
}
|
||||
|
||||
void mousePressed() {
|
||||
if ( (mouseY< rBar.y+5) && (mouseY>rBar.y-5) ) {
|
||||
rMouse = true;
|
||||
} else if ( (mouseY< gBar.y+5) && (mouseY>gBar.y-5) ) {
|
||||
gMouse = true;
|
||||
} else if ( (mouseY< bBar.y+5) && (mouseY>bBar.y-5) ) {
|
||||
bMouse = true;
|
||||
}
|
||||
}
|
||||
void mouseReleased() {
|
||||
rMouse = false;
|
||||
bMouse = false;
|
||||
gMouse = false;
|
||||
}
|
||||
void mouseDragged() {
|
||||
int a = constrain(mouseX, borderSize, width - borderSize);
|
||||
float t = map(a, borderSize, width - borderSize, 0.0, 1.0);
|
||||
if (rMouse) {
|
||||
pRed.softPwmWrite((int)(100-t*100)); //wirte the duty cycle according to t
|
||||
rBar.setProgress(t);
|
||||
} else if (gMouse) {
|
||||
pGreen.softPwmWrite((int)(100-t*100)); //wirte the duty cycle according to t
|
||||
gBar.setProgress(t);
|
||||
} else if (bMouse) {
|
||||
pBlue.softPwmWrite((int)(100-t*100)); //wirte the duty cycle according to t
|
||||
bBar.setProgress(t);
|
||||
}
|
||||
}
|
||||
|
||||
void titleAndSiteInfo() {
|
||||
fill(0);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textSize(40); //set text size
|
||||
text("Colorful LED", width / 2, 40); //title
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20); //site
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*****************************************************
|
||||
* Filename : Sketch_05_1_1_Activebuzzer
|
||||
* Description : Use the mouse to control the Active buzzer ON or OFF
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/14
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
int buzzerPin = 17;
|
||||
boolean buzzerState = false;
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
GPIO.pinMode(buzzerPin, GPIO.OUTPUT);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
titleAndSiteInfo(); //title and site infomation
|
||||
drawBuzzer(); //buzzer img
|
||||
if (buzzerState) {
|
||||
GPIO.digitalWrite(buzzerPin, GPIO.HIGH);
|
||||
drawArc(); //Sounds waves img
|
||||
} else {
|
||||
GPIO.digitalWrite(buzzerPin, GPIO.LOW);
|
||||
}
|
||||
}
|
||||
|
||||
void mouseClicked() { //if the mouse Clicked
|
||||
buzzerState = !buzzerState; //Change the buzzer State
|
||||
}
|
||||
void drawBuzzer() {
|
||||
strokeWeight(1);
|
||||
fill(0);
|
||||
ellipse(width/2, height/2, 50, 50);
|
||||
fill(255);
|
||||
ellipse(width/2, height/2, 10, 10);
|
||||
}
|
||||
void drawArc() {
|
||||
noFill();
|
||||
strokeWeight(8);
|
||||
for (int i=0; i<3; i++) {
|
||||
arc(width/2, height/2, 100*(1+i), 100*(1+i), -PI/4, PI/4, OPEN);
|
||||
}
|
||||
}
|
||||
void titleAndSiteInfo() {
|
||||
fill(0);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textSize(40); //set text size
|
||||
text("Active Buzzer", width / 2, 40); //title
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20); //site
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*****************************************************
|
||||
* Filename : PCF8591
|
||||
* Description : class PCF8591,DAC and ADC
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/20
|
||||
*****************************************************/
|
||||
|
||||
class PCF8591 {
|
||||
private int address;
|
||||
private I2C i2c;
|
||||
//constructor,Parameters for the PCF8591 I2C address
|
||||
public PCF8591(int addr) {
|
||||
address = addr;
|
||||
i2c = new I2C(I2C.list()[0]);
|
||||
}
|
||||
//Read the ADC value of one channel
|
||||
public int analogRead(int chn) {
|
||||
int result = 0;
|
||||
i2c.beginTransmission(address);
|
||||
constrain(chn, 0, 3);
|
||||
i2c.write(0x40 | chn);
|
||||
try {
|
||||
byte[] in = i2c.read(1);
|
||||
result = in[0]&0xff;
|
||||
}
|
||||
catch(Exception e) {
|
||||
println(e);
|
||||
}
|
||||
i2c.endTransmission();
|
||||
return result;
|
||||
}
|
||||
//Read the ADC value of all channels
|
||||
public byte[] analogRead() {
|
||||
i2c.beginTransmission(address);
|
||||
i2c.write(0x44);
|
||||
i2c.endTransmission();
|
||||
byte[] in = i2c.read(4);
|
||||
return in;
|
||||
}
|
||||
//Write the DACvalue
|
||||
public void analogWrite(int data) {
|
||||
i2c.beginTransmission(address);
|
||||
i2c.write(0x40);
|
||||
i2c.write(data);
|
||||
i2c.endTransmission();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*****************************************************
|
||||
* Filename : Sketch_06_1_1_PCF8591
|
||||
* Description : ADC and DAC of PCF8591
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/20
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
//Create a object of class PCF8591
|
||||
PCF8591 pcf = new PCF8591(0x48);
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
}
|
||||
void draw() {
|
||||
int adc = pcf.analogRead(0); //Read the ADC value of channel 0
|
||||
float volt = adc*3.3/255.0; //calculate the voltage
|
||||
pcf.analogWrite(adc); //Write the DAC
|
||||
background(255);
|
||||
titleAndSiteInfo();
|
||||
|
||||
fill(0);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textSize(30);
|
||||
text("ADC: "+nf(adc, 3, 0), width / 2, height/2+50);
|
||||
textSize(30);
|
||||
text("DAC: "+nf(adc, 3, 0), width / 2, height/2+100);
|
||||
textSize(40); //set text size
|
||||
text("Voltage: "+nf(volt, 0, 2)+"V", width / 2, height/2); //
|
||||
}
|
||||
void titleAndSiteInfo() {
|
||||
fill(0);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textSize(40); //set text size
|
||||
text("ADC & DAC", width / 2, 40); //title
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20); //site
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*****************************************************
|
||||
* Filename : PCF8591
|
||||
* Description : class PCF8591,DAC and ADC
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/20
|
||||
*****************************************************/
|
||||
|
||||
class PCF8591 {
|
||||
private int address;
|
||||
private I2C i2c;
|
||||
//constructor,Parameters for the PCF8591 I2C address
|
||||
public PCF8591(int addr) {
|
||||
address = addr;
|
||||
i2c = new I2C(I2C.list()[0]);
|
||||
}
|
||||
//Read the ADC value of one channel
|
||||
public int analogRead(int chn) {
|
||||
int result = 0;
|
||||
i2c.beginTransmission(address);
|
||||
constrain(chn, 0, 3);
|
||||
i2c.write(0x40 | chn);
|
||||
try {
|
||||
byte[] in = i2c.read(1);
|
||||
result = in[0]&0xff;
|
||||
}
|
||||
catch(Exception e) {
|
||||
println(e);
|
||||
}
|
||||
i2c.endTransmission();
|
||||
return result;
|
||||
}
|
||||
//Read the ADC value of all channels
|
||||
public byte[] analogRead() {
|
||||
i2c.beginTransmission(address);
|
||||
i2c.write(0x44);
|
||||
i2c.endTransmission();
|
||||
byte[] in = i2c.read(4);
|
||||
return in;
|
||||
}
|
||||
//Write the DACvalue
|
||||
public void analogWrite(int data) {
|
||||
i2c.beginTransmission(address);
|
||||
i2c.write(0x40);
|
||||
i2c.write(data);
|
||||
i2c.endTransmission();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import processing.io.*;
|
||||
|
||||
class SOFTPWM {
|
||||
public int pin=-1;
|
||||
public long range = -1;
|
||||
private Thread t = new Thread(new myThread());
|
||||
//private Thread t = new Thread();
|
||||
public long marks = 0; //high level time of period
|
||||
public long space = 0; //low level time of period
|
||||
public SOFTPWM(int iPin, int dc, int pwmRange) {
|
||||
pin = iPin;
|
||||
range = pwmRange*100000; //unit : 0.1ms
|
||||
marks = dc*100000;
|
||||
GPIO.pinMode(pin, GPIO.OUTPUT);
|
||||
t.start();
|
||||
}
|
||||
public void softPwmWrite(int value) {
|
||||
value *= 100000;
|
||||
constrain(value, 0, range);
|
||||
marks = value;
|
||||
}
|
||||
public void softPwmStop() {
|
||||
t.stop();
|
||||
GPIO.digitalWrite(pin, GPIO.LOW);
|
||||
}
|
||||
private class myThread implements Runnable {
|
||||
public void run() {
|
||||
while (true) {
|
||||
space = range - marks;
|
||||
if (marks !=0 ) {
|
||||
GPIO.digitalWrite(pin, GPIO.HIGH);
|
||||
delayMicroSeconds(marks);
|
||||
}
|
||||
if (space !=0 ) {
|
||||
GPIO.digitalWrite(pin, GPIO.LOW);
|
||||
delayMicroSeconds(space);
|
||||
}
|
||||
//println("mark : "+marks+" space : "+space);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SEC {
|
||||
public long msec;
|
||||
public int nsec;
|
||||
}
|
||||
void delayMicroSeconds(long howlong) {
|
||||
SEC s = new SEC();
|
||||
s.msec = howlong / 1000000;
|
||||
s.nsec = (int)howlong % 1000000;
|
||||
try {
|
||||
Thread.sleep(s.msec, s.nsec);
|
||||
}
|
||||
catch(Exception e) {
|
||||
println(e);
|
||||
println("msec: "+s.msec+" nsec: "+s.nsec);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*****************************************************
|
||||
* Filename : Sketch_07_1_1_SoftLight
|
||||
* Description : control the brightness of led through a potentiometer
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/20
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
int ledPin = 17; //led
|
||||
//Create a object of class PCF8591
|
||||
PCF8591 pcf = new PCF8591(0x48);
|
||||
SOFTPWM p = new SOFTPWM(ledPin, 0, 100);
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
}
|
||||
void draw() {
|
||||
int adc = pcf.analogRead(0); //Read the ADC value of channel 0
|
||||
float volt = adc*3.3/255.0; //calculate the voltage
|
||||
float dt = adc/255.0;
|
||||
p.softPwmWrite((int)(dt*100)); //output the pwm
|
||||
background(255);
|
||||
titleAndSiteInfo();
|
||||
|
||||
fill(255, 255-dt*255, 255-dt*255); //cycle
|
||||
noStroke(); //no border
|
||||
ellipse(width/2, height/2, 100, 100);
|
||||
|
||||
fill(0);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textSize(30);
|
||||
text("ADC: "+nf(adc, 3, 0), width / 2, height/2+130);
|
||||
text("Voltage: "+nf(volt, 0, 2)+"V", width / 2, height/2+100); //
|
||||
}
|
||||
void titleAndSiteInfo() {
|
||||
fill(0);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textSize(40); //set text size
|
||||
text("SoftLight", width / 2, 40); //title
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20); //site
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*****************************************************
|
||||
* Filename : PCF8591
|
||||
* Description : class PCF8591,DAC and ADC
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/20
|
||||
*****************************************************/
|
||||
|
||||
class PCF8591 {
|
||||
private int address;
|
||||
private I2C i2c;
|
||||
//constructor,Parameters for the PCF8591 I2C address
|
||||
public PCF8591(int addr) {
|
||||
address = addr;
|
||||
i2c = new I2C(I2C.list()[0]);
|
||||
}
|
||||
//Read the ADC value of one channel
|
||||
public int analogRead(int chn) {
|
||||
int result = 0;
|
||||
i2c.beginTransmission(address);
|
||||
constrain(chn, 0, 3);
|
||||
i2c.write(0x40 | chn);
|
||||
try {
|
||||
byte[] in = i2c.read(1);
|
||||
result = in[0]&0xff;
|
||||
}
|
||||
catch(Exception e) {
|
||||
println(e);
|
||||
}
|
||||
i2c.endTransmission();
|
||||
return result;
|
||||
}
|
||||
//Read the ADC value of all channels
|
||||
public byte[] analogRead() {
|
||||
i2c.beginTransmission(address);
|
||||
i2c.write(0x44);
|
||||
i2c.endTransmission();
|
||||
byte[] in = i2c.read(4);
|
||||
return in;
|
||||
}
|
||||
//Write the DACvalue
|
||||
public void analogWrite(int data) {
|
||||
i2c.beginTransmission(address);
|
||||
i2c.write(0x40);
|
||||
i2c.write(data);
|
||||
i2c.endTransmission();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*****************************************************
|
||||
* Filename : Sketch_08_1_1_Thermometer
|
||||
* Description : A DIY Thermometer
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/21
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
//Create a object of class PCF8591
|
||||
PCF8591 pcf = new PCF8591(0x48);
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
}
|
||||
void draw() {
|
||||
int adc = pcf.analogRead(0); //Read the ADC value of channel 0
|
||||
float volt = adc*3.3/255.0; //calculate the voltage
|
||||
float tempK,tempC,Rt; //
|
||||
Rt = 10*volt / (3.3-volt); //calculate the resistance value of thermistor
|
||||
tempK = 1/(1/(273.15+25) + log(Rt/10)/3950); //calaulate temperature(Kelvin)
|
||||
tempC = tempK - 273.15; //calaulate temperature(Celsius)
|
||||
|
||||
background(255);
|
||||
titleAndSiteInfo();
|
||||
|
||||
fill(0);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textSize(30);
|
||||
text("ADC: "+nf(adc, 0, 0), width / 2, height/2+50);
|
||||
textSize(30);
|
||||
text("voltage: "+nf(volt, 0, 2)+"V", width / 2, height/2+100);
|
||||
textSize(40); //set text size
|
||||
text("Temperature: "+nf(tempC, 0, 2)+" C", width / 2, height/2); //
|
||||
}
|
||||
void titleAndSiteInfo() {
|
||||
fill(0);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textSize(40); //set text size
|
||||
text("Thermometer", width / 2, 40); //title
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20); //site
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*****************************************************
|
||||
* Filename : BUTTON
|
||||
* Description : class BUTTON
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/22
|
||||
*****************************************************/
|
||||
class BUTTON {
|
||||
public int x, y, w, h;
|
||||
public String txt;
|
||||
private int bgr, bgg, bgb;
|
||||
private int tr, tg, tb;
|
||||
public BUTTON(int ix, int iy, int iw, int ih) {
|
||||
setPosition(ix, iy);
|
||||
setSize(iw, ih);
|
||||
setText("BTN");
|
||||
setBgColor(0, 0, 0);
|
||||
setTextColor(255,255,255);
|
||||
}
|
||||
public void create() {
|
||||
pushMatrix();
|
||||
translate(x,y);
|
||||
fill(bgr, bgg, bgb);
|
||||
rect(0, 0, w, h);
|
||||
fill(tr, tg, tb);
|
||||
textSize(min(w,h)/2);
|
||||
textAlign(CENTER, CENTER);
|
||||
text(txt, w/2, h/2);
|
||||
popMatrix();
|
||||
}
|
||||
public void setBgColor(int ir, int ig, int ib) {
|
||||
bgr = ir;
|
||||
bgg = ig;
|
||||
bgb = ib;
|
||||
}
|
||||
public void setText(String str) {
|
||||
txt = str;
|
||||
}
|
||||
public void setTextColor(int ir, int ig, int ib) {
|
||||
tr = ir;
|
||||
tg = ig;
|
||||
tb = ib;
|
||||
}
|
||||
public void setSize(int iw, int ih) {
|
||||
w = iw;
|
||||
h = ih;
|
||||
}
|
||||
public void setPosition(int ix, int iy) {
|
||||
x= ix;
|
||||
y = iy;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*****************************************************
|
||||
* Filename : MOTOR
|
||||
* Description : class MOTOR
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/22
|
||||
*****************************************************/
|
||||
|
||||
import processing.io.*;
|
||||
|
||||
class MOTOR {
|
||||
int mPin1, mPin2, enPin;
|
||||
SOFTPWM p;
|
||||
public int dir;
|
||||
final public int CW = 1, CCW = 2, STOP = 3;
|
||||
public MOTOR(int pin1, int pin2, int enablePin) {
|
||||
mPin1 = pin1;
|
||||
mPin2 = pin2;
|
||||
enPin = enablePin;
|
||||
GPIO.pinMode(mPin1, GPIO.OUTPUT);
|
||||
GPIO.pinMode(mPin2, GPIO.OUTPUT);
|
||||
p = new SOFTPWM(enPin, 0, 100);
|
||||
dir = 0;
|
||||
}
|
||||
public void start(int dir, int speed) {
|
||||
switch(dir) {
|
||||
case CW:
|
||||
GPIO.digitalWrite(mPin1, GPIO.HIGH);
|
||||
GPIO.digitalWrite(mPin2, GPIO.LOW);
|
||||
break;
|
||||
case CCW:
|
||||
GPIO.digitalWrite(mPin1, GPIO.LOW);
|
||||
GPIO.digitalWrite(mPin2, GPIO.HIGH);
|
||||
break;
|
||||
case STOP:
|
||||
GPIO.digitalWrite(mPin1, GPIO.LOW);
|
||||
GPIO.digitalWrite(mPin2, GPIO.LOW);
|
||||
break;
|
||||
default:
|
||||
GPIO.digitalWrite(mPin1, GPIO.LOW);
|
||||
GPIO.digitalWrite(mPin2, GPIO.LOW);
|
||||
break;
|
||||
}
|
||||
constrain(speed, 0, 100);
|
||||
p.softPwmWrite(speed);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*****************************************************
|
||||
* Filename : ProgressBar
|
||||
* Description : class ProgressBar
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/22
|
||||
*****************************************************/
|
||||
|
||||
class ProgressBar {
|
||||
|
||||
int x, y;
|
||||
int barLength;
|
||||
float progress;
|
||||
String title;
|
||||
public ProgressBar(int ix, int iy, int barlen) {
|
||||
x = ix;
|
||||
y = iy;
|
||||
barLength = barlen;
|
||||
progress = 0;
|
||||
title = "Progress";
|
||||
}
|
||||
public void setTitle(String str){
|
||||
title = str;
|
||||
}
|
||||
public void setProgress(float pgress) {
|
||||
constrain(pgress, 0, 1.0);
|
||||
progress = pgress;
|
||||
}
|
||||
public void create() {
|
||||
pushMatrix();
|
||||
translate(x, y);
|
||||
textAlign(CENTER);
|
||||
textSize(16);
|
||||
barBgStyle(); //progressbar bg
|
||||
line(0, 0, barLength, 0);
|
||||
line(barLength, -5, barLength, 5);
|
||||
|
||||
barStyle(); //progressbar
|
||||
line(0, -5, 0, 5);
|
||||
line(0, 0, progress*barLength, 0);
|
||||
|
||||
barLabelStyle(); //progressbar label
|
||||
text(title+" : "+nf(progress*100, 2, 2)+"%", barLength/2, -5);
|
||||
popMatrix();
|
||||
}
|
||||
public void create(float pgress) {
|
||||
setProgress(pgress);
|
||||
pushMatrix();
|
||||
translate(x, y);
|
||||
|
||||
barBgStyle(); //progressbar bg
|
||||
line(0, 0, barLength, 0);
|
||||
line(barLength, -5, barLength, 5);
|
||||
|
||||
barStyle(); //progressbar
|
||||
line(0, -5, 0, 5);
|
||||
line(0, 0, progress*barLength, 0);
|
||||
|
||||
barLabelStyle(); //progressbar label
|
||||
text(title+" : "+nf(progress*100, 2, 2)+"%", barLength/2, -5);
|
||||
popMatrix();
|
||||
}
|
||||
void barBgStyle() {
|
||||
stroke(220);
|
||||
noFill();
|
||||
}
|
||||
|
||||
void barStyle() {
|
||||
stroke(50);
|
||||
noFill();
|
||||
}
|
||||
|
||||
void barLabelStyle() {
|
||||
noStroke();
|
||||
fill(120);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*****************************************************
|
||||
* Filename : SOFTPWM
|
||||
* Description : class SOFTPWM
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/22
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
class SOFTPWM {
|
||||
public int pin=-1;
|
||||
public long range = -1;
|
||||
private Thread t = new Thread(new myThread());
|
||||
//private Thread t = new Thread();
|
||||
public long marks = 0; //high level time of period
|
||||
public long space = 0; //low level time of period
|
||||
public SOFTPWM(int iPin, int dc, int pwmRange) {
|
||||
pin = iPin;
|
||||
range = pwmRange*100000; //unit : 0.1ms
|
||||
marks = dc*100000;
|
||||
GPIO.pinMode(pin, GPIO.OUTPUT);
|
||||
t.start();
|
||||
}
|
||||
public void softPwmWrite(int value) {
|
||||
value *= 100000;
|
||||
constrain(value, 0, range);
|
||||
marks = value;
|
||||
}
|
||||
public void softPwmStop() {
|
||||
t.stop();
|
||||
GPIO.digitalWrite(pin, GPIO.LOW);
|
||||
}
|
||||
private class myThread implements Runnable {
|
||||
public void run() {
|
||||
while (true) {
|
||||
space = range - marks;
|
||||
if (marks !=0 ) {
|
||||
GPIO.digitalWrite(pin, GPIO.HIGH);
|
||||
delayMicroSeconds(marks);
|
||||
}
|
||||
if (space !=0 ) {
|
||||
GPIO.digitalWrite(pin, GPIO.LOW);
|
||||
delayMicroSeconds(space);
|
||||
}
|
||||
//println("mark : "+marks+" space : "+space);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SEC {
|
||||
public long msec;
|
||||
public int nsec;
|
||||
}
|
||||
void delayMicroSeconds(long howlong) {
|
||||
SEC s = new SEC();
|
||||
s.msec = howlong / 1000000;
|
||||
s.nsec = (int)howlong % 1000000;
|
||||
try {
|
||||
Thread.sleep(s.msec, s.nsec);
|
||||
}
|
||||
catch(Exception e) {
|
||||
println(e);
|
||||
println("msec: "+s.msec+" nsec: "+s.nsec);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*****************************************************
|
||||
* Filename : Sketch_09_1_1_Motor
|
||||
* Description : Control speed and direction of the motor
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/22
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
int motorPin1 = 17; //connect to the L293D
|
||||
int motorPin2 = 27;
|
||||
int enablePin = 22;
|
||||
final int borderSize = 45; //border size
|
||||
//MOTOR Object
|
||||
MOTOR motor = new MOTOR(motorPin1, motorPin2, enablePin);
|
||||
ProgressBar mBar; //ProgressBar Object
|
||||
boolean mMouse = false; //determined whether a mouse click the ProgressBar
|
||||
BUTTON btn; //BUTTON Object, For controlling the direction of motor
|
||||
int motorDir = motor.CW; //motor direction
|
||||
float rotaSpeed = 0, rotaPosition = 0; //motor speed
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
mBar = new ProgressBar(borderSize, height-borderSize, width-borderSize*2);
|
||||
mBar.setTitle("Duty Cycle"); //set the ProgressBar's title
|
||||
btn = new BUTTON(45, height - 90, 50, 30); //define the button
|
||||
btn.setBgColor(0, 255, 0); //set button color
|
||||
btn.setText("CW"); //set button text
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
titleAndSiteInfo(); //title and site information
|
||||
strokeWeight(4); //border weight
|
||||
mBar.create(); //create the ProgressBar
|
||||
motor.start(motorDir, (int)(mBar.progress*100)); //control the motor starts to rotate
|
||||
btn.create(); //create the button
|
||||
rotaSpeed = mBar.progress * 0.02 * PI; //virtual fan's rotating speed
|
||||
if (motorDir == motor.CW) {
|
||||
rotaPosition += rotaSpeed;
|
||||
if (rotaPosition >= 2*PI) {
|
||||
rotaPosition = 0;
|
||||
}
|
||||
} else {
|
||||
rotaPosition -= rotaSpeed;
|
||||
if (rotaPosition <= -2*PI) {
|
||||
rotaPosition = 0;
|
||||
}
|
||||
}
|
||||
drawFan(rotaPosition); //show the virtual fan in Display window
|
||||
}
|
||||
//Draw a clover fan according to the stating angle
|
||||
void drawFan(float angle) {
|
||||
constrain(angle, 0, 2*PI);
|
||||
fill(0);
|
||||
for (int i=0; i<3; i++) {
|
||||
arc(width/2, height/2, 200, 200, 2*i*PI/3+angle, (2*i+0.3)*PI/3+angle, PIE);
|
||||
}
|
||||
fill(0);
|
||||
ellipse(width/2, height/2, 30, 30);
|
||||
fill(128);
|
||||
ellipse(width/2, height/2, 15, 15);
|
||||
}
|
||||
|
||||
void mousePressed() {
|
||||
if ( (mouseY< mBar.y+5) && (mouseY>mBar.y-5) ) {
|
||||
mMouse = true; //the mouse click the progressBar
|
||||
} else if ((mouseY< btn.y+btn.h) && (mouseY>btn.y)
|
||||
&& (mouseX< btn.x+btn.w) && (mouseX>btn.x)) { // the mouse click the button
|
||||
if (motorDir == motor.CW) { //change the direction of rotation of motor
|
||||
motorDir = motor.CCW;
|
||||
btn.setBgColor(255, 0, 0);
|
||||
btn.setText("CCW");
|
||||
} else if (motorDir == motor.CCW) {
|
||||
motorDir = motor.CW;
|
||||
btn.setBgColor(0, 255, 0);
|
||||
btn.setText("CW");
|
||||
}
|
||||
}
|
||||
}
|
||||
void mouseReleased() {
|
||||
mMouse = false;
|
||||
}
|
||||
void mouseDragged() {
|
||||
int a = constrain(mouseX, borderSize, width - borderSize);
|
||||
float t = map(a, borderSize, width - borderSize, 0.0, 1.0);
|
||||
if (mMouse) {
|
||||
mBar.setProgress(t);
|
||||
}
|
||||
}
|
||||
void titleAndSiteInfo() {
|
||||
fill(0);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textSize(40); //set text size
|
||||
text("Motor", width / 2, 40); //title
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20); //site
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*****************************************************
|
||||
* Filename : IC74HC595
|
||||
* Description : class IC74HC595
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/22
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
class IC74HC595 {
|
||||
final int LSBFIRST = 1;
|
||||
final int MSBFIRST = 2;
|
||||
int dataPin, latchPin, clockPin;
|
||||
public IC74HC595(int dPin, int lPin, int cPin) {
|
||||
dataPin = dPin;
|
||||
latchPin = lPin;
|
||||
clockPin = cPin;
|
||||
GPIO.pinMode(dataPin, GPIO.OUTPUT);
|
||||
GPIO.pinMode(latchPin, GPIO.OUTPUT);
|
||||
GPIO.pinMode(clockPin, GPIO.OUTPUT);
|
||||
}
|
||||
public void write(int order,int value) {
|
||||
constrain(order,1,2);
|
||||
GPIO.digitalWrite(latchPin,GPIO.LOW);
|
||||
shiftOut(order,value);
|
||||
GPIO.digitalWrite(latchPin,GPIO.HIGH);
|
||||
}
|
||||
private void shiftOut(int order, int val) {
|
||||
for (int i = 0; i<8; i++) {
|
||||
GPIO.digitalWrite(clockPin, GPIO.LOW);
|
||||
if (order == LSBFIRST) {
|
||||
GPIO.digitalWrite(dataPin, ((0x01&(val>>i))==0x01) ? GPIO.HIGH : GPIO.LOW);
|
||||
} else if (order == MSBFIRST) {
|
||||
GPIO.digitalWrite(dataPin, ((0x80&(val<<i))==0x80) ? GPIO.HIGH : GPIO.LOW);
|
||||
}
|
||||
GPIO.digitalWrite(clockPin, GPIO.HIGH);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*****************************************************
|
||||
* Filename : ProgressBar
|
||||
* Description : class ProgressBar
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/22
|
||||
*****************************************************/
|
||||
|
||||
class ProgressBar {
|
||||
|
||||
int x, y;
|
||||
int barLength;
|
||||
float progress;
|
||||
String title;
|
||||
public ProgressBar(int ix, int iy, int barlen) {
|
||||
x = ix;
|
||||
y = iy;
|
||||
barLength = barlen;
|
||||
progress = 0;
|
||||
title = "Progress";
|
||||
}
|
||||
public void setTitle(String str){
|
||||
title = str;
|
||||
}
|
||||
public void setProgress(float pgress) {
|
||||
constrain(pgress, 0, 1.0);
|
||||
progress = pgress;
|
||||
}
|
||||
public void create() {
|
||||
pushMatrix();
|
||||
translate(x, y);
|
||||
textAlign(CENTER);
|
||||
textSize(16);
|
||||
barBgStyle(); //progressbar bg
|
||||
line(0, 0, barLength, 0);
|
||||
line(barLength, -5, barLength, 5);
|
||||
|
||||
barStyle(); //progressbar
|
||||
line(0, -5, 0, 5);
|
||||
line(0, 0, progress*barLength, 0);
|
||||
|
||||
barLabelStyle(); //progressbar label
|
||||
text(title+" : "+nf(progress*100, 2, 2)+"%", barLength/2, -5);
|
||||
popMatrix();
|
||||
}
|
||||
public void create(float pgress) {
|
||||
setProgress(pgress);
|
||||
pushMatrix();
|
||||
translate(x, y);
|
||||
|
||||
barBgStyle(); //progressbar bg
|
||||
line(0, 0, barLength, 0);
|
||||
line(barLength, -5, barLength, 5);
|
||||
|
||||
barStyle(); //progressbar
|
||||
line(0, -5, 0, 5);
|
||||
line(0, 0, progress*barLength, 0);
|
||||
|
||||
barLabelStyle(); //progressbar label
|
||||
text(title+" : "+nf(progress*100, 2, 2)+"%", barLength/2, -5);
|
||||
popMatrix();
|
||||
}
|
||||
void barBgStyle() {
|
||||
stroke(220);
|
||||
noFill();
|
||||
}
|
||||
|
||||
void barStyle() {
|
||||
stroke(50);
|
||||
noFill();
|
||||
}
|
||||
|
||||
void barLabelStyle() {
|
||||
noStroke();
|
||||
fill(120);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*****************************************************
|
||||
* Filename : Sketch_10_1_1_LightWater
|
||||
* Description : Control the LEDBar Graph by 74HC595
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/22
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
int dataPin = 17; //connect to the 74HC595
|
||||
int latchPin = 27;
|
||||
int clockPin = 22;
|
||||
final int borderSize = 45; //border size
|
||||
ProgressBar mBar; //ProgressBar Object
|
||||
IC74HC595 ic; //IC74HC595 Object
|
||||
boolean mMouse = false; //determined whether a mouse click the ProgressBar
|
||||
int leds = 0x01; //number of led on
|
||||
int lastMoveTime = 0; //led last move time point
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
mBar = new ProgressBar(borderSize, height-borderSize, width-borderSize*2);
|
||||
mBar.setTitle("Speed"); //set the ProgressBar's title
|
||||
ic = new IC74HC595(dataPin, latchPin, clockPin);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
titleAndSiteInfo(); //title and site information
|
||||
strokeWeight(4); //border weight
|
||||
mBar.create(); //create the ProgressBar
|
||||
//control the speed of lightwater
|
||||
if (millis() - lastMoveTime > 50/(0.05+mBar.progress)) {
|
||||
lastMoveTime = millis();
|
||||
leds<<=1;
|
||||
if (leds == 0x100)
|
||||
leds = 0x01;
|
||||
}
|
||||
ic.write(ic.LSBFIRST, leds); //write 74HC595
|
||||
|
||||
stroke(0);
|
||||
strokeWeight(1);
|
||||
for (int i=0; i<10; i++) { //draw 10 rectanglar box
|
||||
if (leds == (1<<i)) { //
|
||||
fill(255, 0, 0); //fill the rectanglar box in red color
|
||||
} else {
|
||||
fill(255, 255, 255); //else fill the rectanglar box in white color
|
||||
}
|
||||
rect(25+60*i, 90, 50, 180); //draw a rectanglar box
|
||||
}
|
||||
}
|
||||
|
||||
void mousePressed() {
|
||||
if ( (mouseY< mBar.y+5) && (mouseY>mBar.y-5) ) {
|
||||
mMouse = true; //the mouse click the progressBar
|
||||
}
|
||||
}
|
||||
void mouseReleased() {
|
||||
mMouse = false;
|
||||
}
|
||||
void mouseDragged() {
|
||||
int a = constrain(mouseX, borderSize, width - borderSize);
|
||||
float t = map(a, borderSize, width - borderSize, 0.0, 1.0);
|
||||
if (mMouse) {
|
||||
mBar.setProgress(t);
|
||||
}
|
||||
}
|
||||
void titleAndSiteInfo() {
|
||||
fill(0);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textSize(40); //set text size
|
||||
text("LightWater", width / 2, 40); //title
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20); //site
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*****************************************************
|
||||
* Filename : IC74HC595
|
||||
* Description : class IC74HC595
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/22
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
class IC74HC595 {
|
||||
final int LSBFIRST = 1;
|
||||
final int MSBFIRST = 2;
|
||||
int dataPin, latchPin, clockPin;
|
||||
public IC74HC595(int dPin, int lPin, int cPin) {
|
||||
dataPin = dPin;
|
||||
latchPin = lPin;
|
||||
clockPin = cPin;
|
||||
GPIO.pinMode(dataPin, GPIO.OUTPUT);
|
||||
GPIO.pinMode(latchPin, GPIO.OUTPUT);
|
||||
GPIO.pinMode(clockPin, GPIO.OUTPUT);
|
||||
}
|
||||
public void write(int order,int value) {
|
||||
constrain(order,1,2);
|
||||
GPIO.digitalWrite(latchPin,GPIO.LOW);
|
||||
shiftOut(order,value);
|
||||
GPIO.digitalWrite(latchPin,GPIO.HIGH);
|
||||
}
|
||||
private void shiftOut(int order, int val) {
|
||||
for (int i = 0; i<8; i++) {
|
||||
GPIO.digitalWrite(clockPin, GPIO.LOW);
|
||||
if (order == LSBFIRST) {
|
||||
GPIO.digitalWrite(dataPin, ((0x01&(val>>i))==0x01) ? GPIO.HIGH : GPIO.LOW);
|
||||
} else if (order == MSBFIRST) {
|
||||
GPIO.digitalWrite(dataPin, ((0x80&(val<<i))==0x80) ? GPIO.HIGH : GPIO.LOW);
|
||||
}
|
||||
GPIO.digitalWrite(clockPin, GPIO.HIGH);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*****************************************************
|
||||
* Filename : ProgressBar
|
||||
* Description : class ProgressBar
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/22
|
||||
*****************************************************/
|
||||
|
||||
class ProgressBar {
|
||||
|
||||
int x, y;
|
||||
int barLength;
|
||||
float progress;
|
||||
String title;
|
||||
public ProgressBar(int ix, int iy, int barlen) {
|
||||
x = ix;
|
||||
y = iy;
|
||||
barLength = barlen;
|
||||
progress = 0;
|
||||
title = "Progress";
|
||||
}
|
||||
public void setTitle(String str){
|
||||
title = str;
|
||||
}
|
||||
public void setProgress(float pgress) {
|
||||
constrain(pgress, 0, 1.0);
|
||||
progress = pgress;
|
||||
}
|
||||
public void create() {
|
||||
pushMatrix();
|
||||
translate(x, y);
|
||||
textAlign(CENTER);
|
||||
textSize(16);
|
||||
barBgStyle(); //progressbar bg
|
||||
line(0, 0, barLength, 0);
|
||||
line(barLength, -5, barLength, 5);
|
||||
|
||||
barStyle(); //progressbar
|
||||
line(0, -5, 0, 5);
|
||||
line(0, 0, progress*barLength, 0);
|
||||
|
||||
barLabelStyle(); //progressbar label
|
||||
text(title+" : "+nf(progress*100, 2, 2)+"%", barLength/2, -5);
|
||||
popMatrix();
|
||||
}
|
||||
public void create(float pgress) {
|
||||
setProgress(pgress);
|
||||
pushMatrix();
|
||||
translate(x, y);
|
||||
|
||||
barBgStyle(); //progressbar bg
|
||||
line(0, 0, barLength, 0);
|
||||
line(barLength, -5, barLength, 5);
|
||||
|
||||
barStyle(); //progressbar
|
||||
line(0, -5, 0, 5);
|
||||
line(0, 0, progress*barLength, 0);
|
||||
|
||||
barLabelStyle(); //progressbar label
|
||||
text(title+" : "+nf(progress*100, 2, 2)+"%", barLength/2, -5);
|
||||
popMatrix();
|
||||
}
|
||||
void barBgStyle() {
|
||||
stroke(220);
|
||||
noFill();
|
||||
}
|
||||
|
||||
void barStyle() {
|
||||
stroke(50);
|
||||
noFill();
|
||||
}
|
||||
|
||||
void barLabelStyle() {
|
||||
noStroke();
|
||||
fill(120);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*****************************************************
|
||||
* Filename : Sketch_11_1_1_SSD
|
||||
* Description : Control the Seven-segment display by 74HC595
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/22
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
int dataPin = 17; //connect to the 74HC595
|
||||
int latchPin = 27;
|
||||
int clockPin = 22;
|
||||
final int borderSize = 45; //border size
|
||||
ProgressBar mBar; //ProgressBar Object
|
||||
IC74HC595 ic; //IC74HC595 Object
|
||||
boolean mMouse = false; //determined whether a mouse click the ProgressBar
|
||||
int index = 0; // index of number
|
||||
int lastMoveTime = 0; //led last move time point
|
||||
//encoding for character 0-9 of common anode SevenSegmentDisplay
|
||||
final int[] numCode = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};
|
||||
PFont mFont;
|
||||
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
mBar = new ProgressBar(borderSize, height-borderSize, width-borderSize*2);
|
||||
mBar.setTitle("Speed"); //set the ProgressBar's title
|
||||
ic = new IC74HC595(dataPin, latchPin, clockPin);
|
||||
mFont = loadFont("DigifaceWide-100.vlw"); //create DigifaceWide font
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
titleAndSiteInfo(); //title and site information
|
||||
strokeWeight(4); //border weight
|
||||
mBar.create(); //create the ProgressBar
|
||||
//control the speed of number change
|
||||
if (millis() - lastMoveTime > 50/(0.05+mBar.progress)) {
|
||||
lastMoveTime = millis();
|
||||
index++;
|
||||
if (index > 9) {
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
ic.write(ic.MSBFIRST, numCode[index]); //write 74HC595
|
||||
showNum(index); //show the number in dispaly window
|
||||
}
|
||||
void showNum(int num) {
|
||||
fill(0);
|
||||
textSize(100);
|
||||
textFont(mFont); //digiface font
|
||||
textAlign(CENTER, CENTER);
|
||||
text(num, width/2, height/2);
|
||||
}
|
||||
void mousePressed() {
|
||||
if ( (mouseY< mBar.y+5) && (mouseY>mBar.y-5) ) {
|
||||
mMouse = true; //the mouse click the progressBar
|
||||
}
|
||||
}
|
||||
void mouseReleased() {
|
||||
mMouse = false;
|
||||
}
|
||||
void mouseDragged() {
|
||||
int a = constrain(mouseX, borderSize, width - borderSize);
|
||||
float t = map(a, borderSize, width - borderSize, 0.0, 1.0);
|
||||
if (mMouse) {
|
||||
mBar.setProgress(t);
|
||||
}
|
||||
}
|
||||
void titleAndSiteInfo() {
|
||||
fill(0);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textFont(createFont("", 100)); //default font
|
||||
textSize(40); //set text size
|
||||
text("Seven-segment Display", width / 2, 40); //title
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20); //site
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
/*****************************************************
|
||||
* Filename : IC74HC595
|
||||
* Description : class IC74HC595
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/22
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
class IC74HC595 {
|
||||
final int LSBFIRST = 1;
|
||||
final int MSBFIRST = 2;
|
||||
int dataPin, latchPin, clockPin;
|
||||
public IC74HC595(int dPin, int lPin, int cPin) {
|
||||
dataPin = dPin;
|
||||
latchPin = lPin;
|
||||
clockPin = cPin;
|
||||
GPIO.pinMode(dataPin, GPIO.OUTPUT);
|
||||
GPIO.pinMode(latchPin, GPIO.OUTPUT);
|
||||
GPIO.pinMode(clockPin, GPIO.OUTPUT);
|
||||
}
|
||||
public void write(int order,int value) {
|
||||
constrain(order,1,2);
|
||||
GPIO.digitalWrite(latchPin,GPIO.LOW);
|
||||
shiftOut(order,value);
|
||||
GPIO.digitalWrite(latchPin,GPIO.HIGH);
|
||||
}
|
||||
private void shiftOut(int order, int val) {
|
||||
for (int i = 0; i<8; i++) {
|
||||
GPIO.digitalWrite(clockPin, GPIO.LOW);
|
||||
if (order == LSBFIRST) {
|
||||
GPIO.digitalWrite(dataPin, ((0x01&(val>>i))==0x01) ? GPIO.HIGH : GPIO.LOW);
|
||||
} else if (order == MSBFIRST) {
|
||||
GPIO.digitalWrite(dataPin, ((0x80&(val<<i))==0x80) ? GPIO.HIGH : GPIO.LOW);
|
||||
}
|
||||
GPIO.digitalWrite(clockPin, GPIO.HIGH);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*****************************************************
|
||||
* Filename : ProgressBar
|
||||
* Description : class ProgressBar
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/22
|
||||
*****************************************************/
|
||||
|
||||
class ProgressBar {
|
||||
|
||||
int x, y;
|
||||
int barLength;
|
||||
float progress;
|
||||
String title;
|
||||
public ProgressBar(int ix, int iy, int barlen) {
|
||||
x = ix;
|
||||
y = iy;
|
||||
barLength = barlen;
|
||||
progress = 0;
|
||||
title = "Progress";
|
||||
}
|
||||
public void setTitle(String str){
|
||||
title = str;
|
||||
}
|
||||
public void setProgress(float pgress) {
|
||||
constrain(pgress, 0, 1.0);
|
||||
progress = pgress;
|
||||
}
|
||||
public void create() {
|
||||
pushMatrix();
|
||||
translate(x, y);
|
||||
textAlign(CENTER);
|
||||
textSize(16);
|
||||
barBgStyle(); //progressbar bg
|
||||
line(0, 0, barLength, 0);
|
||||
line(barLength, -5, barLength, 5);
|
||||
|
||||
barStyle(); //progressbar
|
||||
line(0, -5, 0, 5);
|
||||
line(0, 0, progress*barLength, 0);
|
||||
|
||||
barLabelStyle(); //progressbar label
|
||||
text(title+" : "+nf(progress*100, 2, 2)+"%", barLength/2, -5);
|
||||
popMatrix();
|
||||
}
|
||||
public void create(float pgress) {
|
||||
setProgress(pgress);
|
||||
pushMatrix();
|
||||
translate(x, y);
|
||||
|
||||
barBgStyle(); //progressbar bg
|
||||
line(0, 0, barLength, 0);
|
||||
line(barLength, -5, barLength, 5);
|
||||
|
||||
barStyle(); //progressbar
|
||||
line(0, -5, 0, 5);
|
||||
line(0, 0, progress*barLength, 0);
|
||||
|
||||
barLabelStyle(); //progressbar label
|
||||
text(title+" : "+nf(progress*100, 2, 2)+"%", barLength/2, -5);
|
||||
popMatrix();
|
||||
}
|
||||
void barBgStyle() {
|
||||
stroke(220);
|
||||
noFill();
|
||||
}
|
||||
|
||||
void barStyle() {
|
||||
stroke(50);
|
||||
noFill();
|
||||
}
|
||||
|
||||
void barLabelStyle() {
|
||||
noStroke();
|
||||
fill(120);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*****************************************************
|
||||
* Filename : Sketch_11_2_1_FDSSD
|
||||
* Description : Control the 4-Digit 7-segment display by 74HC595
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/09/05
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
int dataPin = 24; //connect to the 74HC595
|
||||
int latchPin = 23;
|
||||
int clockPin = 18;
|
||||
int[] digitPin = {17, 27, 22, 10}; //Connected to a common anode digital tube through the transistor
|
||||
final int borderSize = 45; //border size
|
||||
ProgressBar mBar; //ProgressBar Object
|
||||
IC74HC595 ic; //IC74HC595 Object
|
||||
boolean mMouse = false; //determined whether a mouse click the ProgressBar
|
||||
int index = 0; // index of number
|
||||
int lastMoveTime = 0; //led last move time point
|
||||
//encoding for character 0-9 of common anode SevenSegmentDisplay
|
||||
final int[] numCode = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};
|
||||
PFont mFont;
|
||||
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
for (int i =0; i<4; i++) {
|
||||
GPIO.pinMode(digitPin[i], GPIO.OUTPUT);
|
||||
}
|
||||
mBar = new ProgressBar(borderSize, height-borderSize, width-borderSize*2);
|
||||
mBar.setTitle("Speed"); //set the ProgressBar's title
|
||||
ic = new IC74HC595(dataPin, latchPin, clockPin);
|
||||
mFont = loadFont("DigifaceWide-100.vlw"); //create DigifaceWide font
|
||||
thread("displaySSD");
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
titleAndSiteInfo(); //title and site information
|
||||
strokeWeight(4); //border weight
|
||||
mBar.create(); //create the ProgressBar
|
||||
//control the speed of number change
|
||||
if (millis() - lastMoveTime > 50/(0.05+mBar.progress)) {
|
||||
lastMoveTime = millis();
|
||||
index++;
|
||||
if (index > 9999) {
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
showNum(index); //show the number in dispaly window
|
||||
}
|
||||
void showNum(int num) {
|
||||
fill(0);
|
||||
textSize(100);
|
||||
textFont(mFont); //digiface font
|
||||
textAlign(CENTER, CENTER);
|
||||
text(nf(num,4,0), width/2, height/2);
|
||||
}
|
||||
|
||||
void displaySSD() {
|
||||
while (true) {
|
||||
display(index);
|
||||
}
|
||||
}
|
||||
void selectDigit(int digit) {
|
||||
GPIO.digitalWrite(digitPin[0], ((digit&0x08) == 0x08) ? GPIO.LOW : GPIO.HIGH);
|
||||
GPIO.digitalWrite(digitPin[1], ((digit&0x04) == 0x04) ? GPIO.LOW : GPIO.HIGH);
|
||||
GPIO.digitalWrite(digitPin[2], ((digit&0x02) == 0x02) ? GPIO.LOW : GPIO.HIGH);
|
||||
GPIO.digitalWrite(digitPin[3], ((digit&0x01) == 0x01) ? GPIO.LOW : GPIO.HIGH);
|
||||
}
|
||||
void display(int dec) {
|
||||
selectDigit(0x00);
|
||||
ic.write(ic.MSBFIRST, numCode[dec%10]);
|
||||
selectDigit(0x01); //select the first, and display the single digit
|
||||
delay(1); //display duration
|
||||
selectDigit(0x00);
|
||||
ic.write(ic.MSBFIRST, numCode[dec%100/10]);
|
||||
selectDigit(0x02); //select the second, and display the tens digit
|
||||
delay(1);
|
||||
selectDigit(0x00);
|
||||
ic.write(ic.MSBFIRST, numCode[dec%1000/100]);
|
||||
selectDigit(0x04); //select the third, and display the hundreds digit
|
||||
delay(1);
|
||||
selectDigit(0x00);
|
||||
ic.write(ic.MSBFIRST, numCode[dec%10000/1000]);
|
||||
selectDigit(0x08); //select the fourth, and display the thousands digit
|
||||
delay(1);
|
||||
}
|
||||
void mousePressed() {
|
||||
if ( (mouseY< mBar.y+5) && (mouseY>mBar.y-5) ) {
|
||||
mMouse = true; //the mouse click the progressBar
|
||||
}
|
||||
}
|
||||
void mouseReleased() {
|
||||
mMouse = false;
|
||||
}
|
||||
void mouseDragged() {
|
||||
int a = constrain(mouseX, borderSize, width - borderSize);
|
||||
float t = map(a, borderSize, width - borderSize, 0.0, 1.0);
|
||||
if (mMouse) {
|
||||
mBar.setProgress(t);
|
||||
}
|
||||
}
|
||||
void titleAndSiteInfo() {
|
||||
fill(0);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textFont(createFont("", 100)); //default font
|
||||
textSize(40); //set text size
|
||||
text("4-Digit 7-Segment Display", width / 2, 40); //title
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20); //site
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
/*****************************************************
|
||||
* Filename : IC74HC595
|
||||
* Description : class IC74HC595
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/22
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
class IC74HC595 {
|
||||
final int LSBFIRST = 1;
|
||||
final int MSBFIRST = 2;
|
||||
int dataPin, latchPin, clockPin;
|
||||
public IC74HC595(int dPin, int lPin, int cPin) {
|
||||
dataPin = dPin;
|
||||
latchPin = lPin;
|
||||
clockPin = cPin;
|
||||
GPIO.pinMode(dataPin, GPIO.OUTPUT);
|
||||
GPIO.pinMode(latchPin, GPIO.OUTPUT);
|
||||
GPIO.pinMode(clockPin, GPIO.OUTPUT);
|
||||
}
|
||||
public void write(int order, int value) {
|
||||
constrain(order, 1, 2);
|
||||
GPIO.digitalWrite(latchPin, GPIO.LOW);
|
||||
shiftOut(order, value);
|
||||
GPIO.digitalWrite(latchPin, GPIO.HIGH);
|
||||
}
|
||||
private void shiftOut(int order, int val) {
|
||||
for (int i = 0; i<8; i++) {
|
||||
GPIO.digitalWrite(clockPin, GPIO.LOW);
|
||||
if (order == LSBFIRST) {
|
||||
GPIO.digitalWrite(dataPin, ((0x01&(val>>i))==0x01) ? GPIO.HIGH : GPIO.LOW);
|
||||
} else if (order == MSBFIRST) {
|
||||
GPIO.digitalWrite(dataPin, ((0x80&(val<<i))==0x80) ? GPIO.HIGH : GPIO.LOW);
|
||||
}
|
||||
GPIO.digitalWrite(clockPin, GPIO.HIGH);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*****************************************************
|
||||
* Filename : ProgressBar
|
||||
* Description : class ProgressBar
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/22
|
||||
*****************************************************/
|
||||
|
||||
class ProgressBar {
|
||||
|
||||
int x, y;
|
||||
int barLength;
|
||||
float progress;
|
||||
String title;
|
||||
public ProgressBar(int ix, int iy, int barlen) {
|
||||
x = ix;
|
||||
y = iy;
|
||||
barLength = barlen;
|
||||
progress = 0;
|
||||
title = "Progress";
|
||||
}
|
||||
public void setTitle(String str) {
|
||||
title = str;
|
||||
}
|
||||
public void setProgress(float pgress) {
|
||||
constrain(pgress, 0, 1.0);
|
||||
progress = pgress;
|
||||
}
|
||||
public void create() {
|
||||
pushMatrix();
|
||||
translate(x, y);
|
||||
textAlign(CENTER);
|
||||
textSize(16);
|
||||
barBgStyle(); //progressbar bg
|
||||
line(0, 0, barLength, 0);
|
||||
line(barLength, -5, barLength, 5);
|
||||
|
||||
barStyle(); //progressbar
|
||||
line(0, -5, 0, 5);
|
||||
line(0, 0, progress*barLength, 0);
|
||||
|
||||
barLabelStyle(); //progressbar label
|
||||
text(title+" : "+nf(progress*100, 2, 2)+"%", barLength/2, -5);
|
||||
popMatrix();
|
||||
}
|
||||
public void create(float pgress) {
|
||||
setProgress(pgress);
|
||||
pushMatrix();
|
||||
translate(x, y);
|
||||
|
||||
barBgStyle(); //progressbar bg
|
||||
line(0, 0, barLength, 0);
|
||||
line(barLength, -5, barLength, 5);
|
||||
|
||||
barStyle(); //progressbar
|
||||
line(0, -5, 0, 5);
|
||||
line(0, 0, progress*barLength, 0);
|
||||
|
||||
barLabelStyle(); //progressbar label
|
||||
text(title+" : "+nf(progress*100, 2, 2)+"%", barLength/2, -5);
|
||||
popMatrix();
|
||||
}
|
||||
void barBgStyle() {
|
||||
stroke(220);
|
||||
noFill();
|
||||
}
|
||||
|
||||
void barStyle() {
|
||||
stroke(50);
|
||||
noFill();
|
||||
}
|
||||
|
||||
void barLabelStyle() {
|
||||
noStroke();
|
||||
fill(120);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*****************************************************
|
||||
* Filename : Sketch_12_1_1_LEDMatrix
|
||||
* Description : Control the LEDMatrix by 74HC595
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/22
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
int dataPin = 17; //connect to the 74HC595
|
||||
int latchPin = 27;
|
||||
int clockPin = 22;
|
||||
final int borderSize = 45; //border size
|
||||
ProgressBar mBar; //ProgressBar Object
|
||||
IC74HC595 ic; //IC74HC595 Object
|
||||
boolean mMouse = false; //determined whether a mouse click the ProgressBar
|
||||
int index = 0; // index of number
|
||||
//encoding for smile face
|
||||
final int[] pic = {0x1c, 0x22, 0x51, 0x45, 0x45, 0x51, 0x22, 0x1c};
|
||||
//encoding for character 0-9 of ledmatrix
|
||||
final int[] numCode={
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // " "
|
||||
0x00, 0x00, 0x3E, 0x41, 0x41, 0x3E, 0x00, 0x00, // "0"
|
||||
0x00, 0x00, 0x21, 0x7F, 0x01, 0x00, 0x00, 0x00, // "1"
|
||||
0x00, 0x00, 0x23, 0x45, 0x49, 0x31, 0x00, 0x00, // "2"
|
||||
0x00, 0x00, 0x22, 0x49, 0x49, 0x36, 0x00, 0x00, // "3"
|
||||
0x00, 0x00, 0x0E, 0x32, 0x7F, 0x02, 0x00, 0x00, // "4"
|
||||
0x00, 0x00, 0x79, 0x49, 0x49, 0x46, 0x00, 0x00, // "5"
|
||||
0x00, 0x00, 0x3E, 0x49, 0x49, 0x26, 0x00, 0x00, // "6"
|
||||
0x00, 0x00, 0x60, 0x47, 0x48, 0x70, 0x00, 0x00, // "7"
|
||||
0x00, 0x00, 0x36, 0x49, 0x49, 0x36, 0x00, 0x00, // "8"
|
||||
0x00, 0x00, 0x32, 0x49, 0x49, 0x3E, 0x00, 0x00, // "9"
|
||||
0x00, 0x00, 0x3F, 0x44, 0x44, 0x3F, 0x00, 0x00, // "A"
|
||||
0x00, 0x00, 0x7F, 0x49, 0x49, 0x36, 0x00, 0x00, // "B"
|
||||
0x00, 0x00, 0x3E, 0x41, 0x41, 0x22, 0x00, 0x00, // "C"
|
||||
0x00, 0x00, 0x7F, 0x41, 0x41, 0x3E, 0x00, 0x00, // "D"
|
||||
0x00, 0x00, 0x7F, 0x49, 0x49, 0x41, 0x00, 0x00, // "E"
|
||||
0x00, 0x00, 0x7F, 0x48, 0x48, 0x40, 0x00, 0x00, // "F"
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // " "
|
||||
};
|
||||
myThread t = new myThread(); //create a new thread for ledmatrix
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
mBar = new ProgressBar(borderSize, height-borderSize, width-borderSize*2);
|
||||
mBar.setTitle("Speed"); //set the ProgressBar's title
|
||||
ic = new IC74HC595(dataPin, latchPin, clockPin);
|
||||
t.start(); //thread start
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
titleAndSiteInfo(); //title and site information
|
||||
strokeWeight(4); //border weight
|
||||
mBar.create(); //create the ProgressBar
|
||||
displayNum(hex(index, 1)); //show the number in dispaly window
|
||||
}
|
||||
class myThread extends Thread {
|
||||
public void run() {
|
||||
while (true) {
|
||||
showMatrix(); //show smile picture
|
||||
showNum(); //show the character "0-F"
|
||||
}
|
||||
}
|
||||
}
|
||||
void showMatrix() {
|
||||
for (int j=0; j<100; j++) { //picture show time
|
||||
int x=0x80;
|
||||
for (int i=0; i<8; i++) { //display a frame picture
|
||||
GPIO.digitalWrite(latchPin, GPIO.LOW);
|
||||
ic.shiftOut(ic.MSBFIRST, pic[i]);
|
||||
ic.shiftOut(ic.MSBFIRST, ~x);
|
||||
GPIO.digitalWrite(latchPin, GPIO.HIGH);
|
||||
x>>=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
void showNum() {
|
||||
for (int j=0; j<numCode.length-8; j++) { //where to start showing
|
||||
index = j/8;
|
||||
for (int k =0; k<10*(1.2-mBar.progress); k++) { //speed
|
||||
int x=0x80;
|
||||
for (int i=0; i<8; i++) { //display a frame picture
|
||||
GPIO.digitalWrite(latchPin, GPIO.LOW);
|
||||
ic.shiftOut(ic.MSBFIRST, numCode[j+i]);
|
||||
ic.shiftOut(ic.MSBFIRST, ~x);
|
||||
GPIO.digitalWrite(latchPin, GPIO.HIGH);
|
||||
x>>=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void displayNum(String num) {
|
||||
fill(0);
|
||||
textSize(100);
|
||||
textAlign(CENTER, CENTER);
|
||||
text(num, width/2, height/2);
|
||||
}
|
||||
void mousePressed() {
|
||||
if ( (mouseY< mBar.y+5) && (mouseY>mBar.y-5) ) {
|
||||
mMouse = true; //the mouse click the progressBar
|
||||
}
|
||||
}
|
||||
void mouseReleased() {
|
||||
mMouse = false;
|
||||
}
|
||||
void mouseDragged() {
|
||||
int a = constrain(mouseX, borderSize, width - borderSize);
|
||||
float t = map(a, borderSize, width - borderSize, 0.0, 1.0);
|
||||
if (mMouse) {
|
||||
mBar.setProgress(t);
|
||||
}
|
||||
}
|
||||
void titleAndSiteInfo() {
|
||||
fill(0);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textFont(createFont("", 100)); //default font
|
||||
textSize(40); //set text size
|
||||
text("LEDMatrix Display", width / 2, 40); //title
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20); //site
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
/*****************************************************
|
||||
* Filename : Freenove_LCD
|
||||
* Description : use I2C(pcf8574)control LCD1602
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/24
|
||||
*****************************************************/
|
||||
|
||||
class Freenove_LCD1602 {
|
||||
|
||||
final public int //HD44780U commands
|
||||
CLEAR = 0x01,
|
||||
HOME = 0x02,
|
||||
ENTRY = 0x04,
|
||||
CTRL = 0x08,
|
||||
CDSHIFT= 0x10,
|
||||
FUNC = 0x20,
|
||||
CGRAM = 0x40,
|
||||
DDRAM = 0x80;
|
||||
|
||||
final public int //flags for display entry mode
|
||||
ENTRY_SH = 0x01,
|
||||
ENTRY_ID = 0x02;
|
||||
|
||||
final public int //flags for display/cursor on/off control
|
||||
BLINK_CTRL = 0x01,
|
||||
CURSOR_CTRL = 0x02,
|
||||
DISPLAY_CTRL= 0x04;
|
||||
|
||||
final public int //flags function set
|
||||
FUNC_F = 0x04,
|
||||
FUNC_N = 0x08,
|
||||
FUNC_DL = 0x10,
|
||||
MOVERIGHT = 0x04, //flags for display/cursor shift
|
||||
MOVELEFT = 0x00,
|
||||
DISPLAYMOVE = 0x08,
|
||||
CURSORMOVE = 0x00;
|
||||
|
||||
final public int[] rowOff = {0x00, 0x40, 0x14, 0x54 };
|
||||
private int func = 0, control = 0;
|
||||
PCF8574 pcf;
|
||||
private int rows, cols, rsPin, enPin, rwPin;
|
||||
int displayMode = 0;
|
||||
|
||||
public Freenove_LCD1602(PCF8574 ipcf) {
|
||||
pcf = ipcf;
|
||||
rows = 2;
|
||||
cols = 16;
|
||||
rsPin = 0; //connect to PCF8574 module
|
||||
enPin = 2;
|
||||
rwPin = 1;
|
||||
|
||||
pcf.digitalWrite(rsPin, 0);
|
||||
pcf.digitalWrite(enPin, 0);
|
||||
pcf.digitalWrite(rwPin, 0);
|
||||
delay(35);
|
||||
func = FUNC | FUNC_DL; //set 8-bit mode 3 times
|
||||
put4Command(func>>4);
|
||||
delay(35);
|
||||
put4Command(func>>4);
|
||||
delay(35);
|
||||
put4Command(func>>4);
|
||||
delay(35);
|
||||
func = FUNC; //set 4-bit mode
|
||||
put4Command(func>>4);
|
||||
delay(35);
|
||||
if (rows > 1) {
|
||||
func = FUNC_N;
|
||||
putCommand(func);
|
||||
delay(35);
|
||||
}
|
||||
display(true); //lcd initializtion
|
||||
lcdCursor(false);
|
||||
cursorBlink(false);
|
||||
|
||||
displayMode = ENTRY | ENTRY_ID;
|
||||
putCommand(displayMode);
|
||||
putCommand(CDSHIFT | MOVERIGHT);
|
||||
backLightON();
|
||||
home();
|
||||
lcdClear();
|
||||
}
|
||||
//for sending data/cmds
|
||||
public void sendDataCmd(int data) {
|
||||
int d4 = data & 0xf0;
|
||||
pcf.writeByte(d4 | (pcf.currValue&0x0f));
|
||||
strobe();
|
||||
d4 = (data<<4) & 0xf0;
|
||||
pcf.writeByte(d4 | (pcf.currValue&0x0f));
|
||||
strobe();
|
||||
}
|
||||
//send command
|
||||
public void putCommand(int cmd) {
|
||||
pcf.digitalWrite(rsPin, 0);
|
||||
sendDataCmd(cmd);
|
||||
delay(2);
|
||||
}
|
||||
public void put4Command(int command) {
|
||||
pcf.digitalWrite(rsPin, 0);
|
||||
pcf.writeByte(((command<<4)&0xf0) | (pcf.currValue&0x0f));
|
||||
strobe();
|
||||
}
|
||||
//pulse enable
|
||||
public void strobe() {
|
||||
pcf.digitalWrite(enPin, 1);
|
||||
//delay(1);
|
||||
//delayMicroseconds(50);
|
||||
pcf.digitalWrite(enPin, 0);
|
||||
//delay(1);
|
||||
//delayMicroseconds(50);
|
||||
}
|
||||
//send a data byte to be displayed on the display.
|
||||
public void putChar(char data) {
|
||||
pcf.digitalWrite(rsPin, 1);
|
||||
sendDataCmd(data);
|
||||
}
|
||||
//Send a string to be displayed on the display.
|
||||
public void puts(String str) {
|
||||
for (int i=0; i<str.length(); i++) {
|
||||
putChar(str.charAt(i));
|
||||
}
|
||||
}
|
||||
//turn display, cursor, cursor blinking on/off
|
||||
public void display(boolean state) {
|
||||
if (state) {
|
||||
control |= DISPLAY_CTRL;
|
||||
} else {
|
||||
control &= ~DISPLAY_CTRL;
|
||||
}
|
||||
putCommand(CTRL | control);
|
||||
}
|
||||
public void lcdCursor(boolean state) {
|
||||
if (state) {
|
||||
control |= CURSOR_CTRL;
|
||||
} else {
|
||||
control &= ~CURSOR_CTRL;
|
||||
}
|
||||
putCommand(CTRL | control);
|
||||
}
|
||||
public void cursorBlink(boolean state) {
|
||||
if (state) {
|
||||
control |= BLINK_CTRL;
|
||||
} else {
|
||||
control &= ~BLINK_CTRL;
|
||||
}
|
||||
putCommand(CTRL | control);
|
||||
}
|
||||
//set the position of the cursor on the display
|
||||
public void position(int x, int y) {
|
||||
constrain(x, 0, cols);
|
||||
constrain(y, 0, rows);
|
||||
putCommand(x+(DDRAM | rowOff[y]));
|
||||
}
|
||||
//Home the cursor
|
||||
public void home() {
|
||||
putCommand(HOME);
|
||||
}
|
||||
//clear the screen
|
||||
public void lcdClear() {
|
||||
putCommand(CLEAR);
|
||||
putCommand(HOME);
|
||||
}
|
||||
//turn on the backLight
|
||||
public void backLightON() {
|
||||
pcf.digitalWrite(3, 1);
|
||||
}
|
||||
//turn off the backLight
|
||||
public void backLightOFF() {
|
||||
pcf.digitalWrite(3, 0);
|
||||
}
|
||||
//scroll the display a unit to left
|
||||
public void scrollDisplayLeft() {
|
||||
putCommand(CDSHIFT | DISPLAYMOVE | MOVELEFT);
|
||||
}
|
||||
//scroll the display a unit to right
|
||||
public void scrollDisplayRight() {
|
||||
putCommand(CDSHIFT | DISPLAYMOVE | MOVERIGHT);
|
||||
}
|
||||
//text flows left to right
|
||||
public void leftToRight() {
|
||||
displayMode |= ENTRY_ID;
|
||||
putCommand(ENTRY | displayMode);
|
||||
}
|
||||
//text flows right to left
|
||||
public void rightToLeft() {
|
||||
displayMode &= ~ENTRY_ID;
|
||||
putCommand(ENTRY | displayMode);
|
||||
}
|
||||
//scroll the display follow the cursor
|
||||
public void autoScroll() {
|
||||
displayMode |= ENTRY_SH;
|
||||
putCommand(ENTRY | displayMode);
|
||||
}
|
||||
public void noAutoScroll() {
|
||||
displayMode &= ~ENTRY_SH;
|
||||
putCommand(ENTRY | displayMode);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*****************************************************
|
||||
* Filename : PCF8574
|
||||
* Description : class PCF8574
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/20
|
||||
*****************************************************/
|
||||
|
||||
class PCF8574 {
|
||||
private int address;
|
||||
private I2C i2c;
|
||||
private int currValue;
|
||||
//constructor,Parameters for the PCF8591 I2C address
|
||||
public PCF8574(int addr) {
|
||||
address = addr;
|
||||
i2c = new I2C(I2C.list()[0]);
|
||||
currValue = 0;
|
||||
}
|
||||
//Read the data of one port
|
||||
public int digitalRead(int pin) {
|
||||
int val = readByte();
|
||||
return ((val&(1<<pin)) == (1<<pin)) ? 1 : 0;
|
||||
}
|
||||
//Read data of all ports
|
||||
public int readByte() {
|
||||
//// byte[] in = new byte[0];
|
||||
//int val = 0;
|
||||
//i2c.beginTransmission(address);
|
||||
////i2c.write(0xff);
|
||||
//i2c.endTransmission();
|
||||
//try {
|
||||
// byte[] in = i2c.read(1);
|
||||
// val = in[0]&0xff;
|
||||
//}
|
||||
//catch(Exception e) {
|
||||
// println(e);
|
||||
//}
|
||||
//not yet implement
|
||||
|
||||
return currValue;
|
||||
}
|
||||
//Write the data to one of the ports
|
||||
public void digitalWrite(int pin, int val) {
|
||||
int value = currValue;
|
||||
if (val == GPIO.HIGH) {
|
||||
value |= (1<<pin);
|
||||
} else if (val == GPIO.LOW) {
|
||||
value &= ~(1<<pin);
|
||||
} else {
|
||||
println("value error!");
|
||||
return;
|
||||
}
|
||||
writeByte(value);
|
||||
}
|
||||
//Write the data to all ports
|
||||
public void writeByte(int data) {
|
||||
currValue = data;
|
||||
i2c.beginTransmission(address);
|
||||
i2c.write(data);
|
||||
i2c.endTransmission();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*****************************************************
|
||||
* Filename : Sketch_13_1_1_LCD
|
||||
* Description : Use the I2C-LCD1602 display the string
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/24
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
//Create a object of class PCF8574
|
||||
PCF8574 pcf = new PCF8574(0x27);
|
||||
Freenove_LCD1602 lcd; //Create a lcd object
|
||||
String time = "";
|
||||
String date = "";
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
lcd = new Freenove_LCD1602(pcf);
|
||||
frameRate(2); //set display window frame rate for 2 HZ
|
||||
}
|
||||
void draw() {
|
||||
background(255);
|
||||
titleAndSiteInfo();
|
||||
//get current time
|
||||
time = nf(hour(), 2, 0) + ":" + nf(minute(), 2, 0) + ":" + nf(second(), 2, 0);
|
||||
//get current date
|
||||
date = nf(day(), 2, 0)+"/"+nf(month(), 2, 0)+"/"+nf(year(), 2, 0);
|
||||
lcd.position(4, 0); //show time on the lcd display
|
||||
lcd.puts(time);
|
||||
lcd.position(3, 1); //show date on the lcd display
|
||||
lcd.puts(date);
|
||||
showTime(time, date); //show time/date on the display window
|
||||
}
|
||||
void showTime(String time, String date) {
|
||||
fill(0);
|
||||
textAlign(CENTER, CENTER);
|
||||
textSize(50);
|
||||
text(time, width/2, height/2);
|
||||
textSize(30);
|
||||
text(date, width/2, height/2+50);
|
||||
}
|
||||
void titleAndSiteInfo() {
|
||||
fill(0);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textSize(40); //set text size
|
||||
text("I2C-LCD1602", width / 2, 40); //title
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20); //site
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*****************************************************
|
||||
* Filename : PCF8591
|
||||
* Description : class PCF8591,DAC and ADC
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/20
|
||||
*****************************************************/
|
||||
|
||||
class PCF8591 {
|
||||
private int address;
|
||||
private I2C i2c;
|
||||
//constructor,Parameters for the PCF8591 I2C address
|
||||
public PCF8591(int addr) {
|
||||
address = addr;
|
||||
i2c = new I2C(I2C.list()[0]);
|
||||
}
|
||||
//Read the ADC value of one channel
|
||||
//read twice,otherwise errors will occur
|
||||
public int analogRead(int chn) {
|
||||
i2c.beginTransmission(address);
|
||||
constrain(chn, 0, 3);
|
||||
i2c.write(0x40 | chn);
|
||||
byte[] in = i2c.read(1);
|
||||
int result = in[0]&0xff;
|
||||
i2c.endTransmission();
|
||||
|
||||
i2c.beginTransmission(address);
|
||||
constrain(chn, 0, 3);
|
||||
i2c.write(0x40 | chn);
|
||||
in = i2c.read(1);
|
||||
result = in[0]&0xff;
|
||||
i2c.endTransmission();
|
||||
return result;
|
||||
}
|
||||
//Read the ADC value of all channels
|
||||
public byte[] analogRead() {
|
||||
i2c.beginTransmission(address);
|
||||
i2c.write(0x44);
|
||||
//i2c.endTransmission();
|
||||
//i2c.beginTransmission(address);
|
||||
//i2c.write(0x44);
|
||||
byte[] in = i2c.read(4);
|
||||
//i2c.endTransmission();
|
||||
return in;
|
||||
}
|
||||
//Write the DACvalue
|
||||
public void analogWrite(int data) {
|
||||
i2c.beginTransmission(address);
|
||||
i2c.write(0x40);
|
||||
i2c.write(data);
|
||||
i2c.endTransmission();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*****************************************************
|
||||
* Filename : Sketch_14_1_1_Joystick
|
||||
* Description : Display the position of the joystick
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/29
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
//Create a object of class PCF8591
|
||||
PCF8591 pcf = new PCF8591(0x48);
|
||||
int cx, cy, cd, cr; //define the center point,side length & half.
|
||||
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
cx = width/2; //center of the display window
|
||||
cy = height/2; //
|
||||
cd = (int)(height/1.5);
|
||||
cr = cd /2;
|
||||
}
|
||||
void draw() {
|
||||
int x=0, y=0, z=0;
|
||||
x = pcf.analogRead(2); //read the ADC of joystick
|
||||
y = pcf.analogRead(1); //
|
||||
z = pcf.analogRead(0);
|
||||
background(102);
|
||||
titleAndSiteInfo();
|
||||
fill(0);
|
||||
textSize(20);
|
||||
textAlign(LEFT,TOP);
|
||||
text("X:"+x+"\nY:"+y+"\nZ:"+z,10,10);
|
||||
|
||||
fill(255); //wall color
|
||||
rect(cx-cr, cy-cr, cd, cd);
|
||||
fill(constrain(z, 255, 0)); //joysitck color
|
||||
ellipse(map(x, 0, 255, cx-cr, cx+cr), map(y, 0, 255, cy-cr, cy+cr), 50, 50);
|
||||
}
|
||||
void titleAndSiteInfo() {
|
||||
fill(0);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textSize(40); //set text size
|
||||
text("Joystick", width / 2, 40); //title
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20); //site
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*****************************************************
|
||||
* Filename : BUTTON
|
||||
* Description : class BUTTON
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/22
|
||||
*****************************************************/
|
||||
class BUTTON {
|
||||
public int x, y, w, h;
|
||||
public String txt;
|
||||
private int bgr, bgg, bgb;
|
||||
private int tr, tg, tb;
|
||||
public BUTTON(int ix, int iy, int iw, int ih) {
|
||||
setPosition(ix, iy);
|
||||
setSize(iw, ih);
|
||||
setText("BTN");
|
||||
setBgColor(0, 0, 0);
|
||||
setTextColor(255,255,255);
|
||||
}
|
||||
public void create() {
|
||||
pushMatrix();
|
||||
translate(x,y);
|
||||
fill(bgr, bgg, bgb);
|
||||
rect(0, 0, w, h);
|
||||
fill(tr, tg, tb);
|
||||
textSize(min(w,h)/2);
|
||||
textAlign(CENTER, CENTER);
|
||||
text(txt, w/2, h/2);
|
||||
popMatrix();
|
||||
}
|
||||
public void setBgColor(int ir, int ig, int ib) {
|
||||
bgr = ir;
|
||||
bgg = ig;
|
||||
bgb = ib;
|
||||
}
|
||||
public void setText(String str) {
|
||||
txt = str;
|
||||
}
|
||||
public void setTextColor(int ir, int ig, int ib) {
|
||||
tr = ir;
|
||||
tg = ig;
|
||||
tb = ib;
|
||||
}
|
||||
public void setSize(int iw, int ih) {
|
||||
w = iw;
|
||||
h = ih;
|
||||
}
|
||||
public void setPosition(int ix, int iy) {
|
||||
x= ix;
|
||||
y = iy;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* class SingleKey
|
||||
* Author Freenove (http://www.freenove.com)
|
||||
* Date 2016/08/27
|
||||
******************************************************************************
|
||||
* Brief
|
||||
* This class is used to get a single button key value (GPIO numbering)
|
||||
******************************************************************************
|
||||
* Copyright
|
||||
* Copyright © Freenove (http://www.freenove.com)
|
||||
* License
|
||||
* Creative Commons Attribution ShareAlike 3.0
|
||||
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
|
||||
******************************************************************************
|
||||
*/
|
||||
int keyValue = -1;
|
||||
class SingleKey {
|
||||
final int IDLE = 0,
|
||||
PRESSED = 1,
|
||||
HOLD = 2,
|
||||
RELEASED = 3;
|
||||
int btnState = IDLE;
|
||||
boolean isPressed = false;
|
||||
boolean isHold = false;
|
||||
long holdTimer = 0;
|
||||
final int holdTime = 500;
|
||||
boolean changeState = false;
|
||||
int lastButtonIOState = GPIO.HIGH;
|
||||
int buttonIOState=GPIO.HIGH;
|
||||
int nowButtonState;
|
||||
boolean buttonChanged = false;
|
||||
int lastChangeTime;
|
||||
int decounceTime = 50;
|
||||
int pin;
|
||||
public SingleKey(int Pin) {
|
||||
pin = Pin;
|
||||
GPIO.pinMode(pin, GPIO.INPUT);
|
||||
}
|
||||
|
||||
void keyScan() {
|
||||
nowButtonState =GPIO.digitalRead(pin);
|
||||
if (nowButtonState != lastButtonIOState) {
|
||||
lastChangeTime = millis();
|
||||
}
|
||||
if (millis() - lastChangeTime > decounceTime) {
|
||||
if (buttonIOState != nowButtonState) {
|
||||
buttonIOState = nowButtonState;
|
||||
changeState = true;
|
||||
if (buttonIOState == GPIO.LOW) {
|
||||
//btnState = PRESSED;
|
||||
//keyValue = pin;
|
||||
//println("Key is Pressed !! ");
|
||||
} else if (buttonIOState == GPIO.HIGH) {
|
||||
//println("Key is Released !! ");
|
||||
}
|
||||
}
|
||||
}
|
||||
switch(btnState) {
|
||||
case IDLE:
|
||||
if (changeState) {
|
||||
changeState = false;
|
||||
btnState = PRESSED;
|
||||
holdTimer = millis();
|
||||
keyValue = pin;
|
||||
isPressed = true;
|
||||
}
|
||||
break;
|
||||
case PRESSED:
|
||||
if (millis() - holdTimer > holdTime) {
|
||||
btnState = HOLD;
|
||||
keyValue = pin;
|
||||
isPressed = true;
|
||||
isHold = true;
|
||||
} else if (changeState) {
|
||||
changeState = false;
|
||||
btnState = RELEASED;
|
||||
} else {
|
||||
keyValue = -1;
|
||||
isPressed = false;
|
||||
}
|
||||
break;
|
||||
case HOLD:
|
||||
keyValue = pin;
|
||||
isPressed = true;
|
||||
isHold = true;
|
||||
if (changeState) {
|
||||
changeState = false;
|
||||
btnState = RELEASED;
|
||||
}
|
||||
break;
|
||||
case RELEASED:
|
||||
keyValue = -1;
|
||||
isPressed = false;
|
||||
isHold = false;
|
||||
btnState = IDLE;
|
||||
break;
|
||||
}
|
||||
lastButtonIOState = nowButtonState;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*****************************************************
|
||||
* Filename : Sketch_15_1_1_Relay
|
||||
* Description : Control the Motor by Relay
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/30
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
int relayPin = 17;
|
||||
int buttonPin = 18;
|
||||
SingleKey skey = new SingleKey(buttonPin);
|
||||
boolean relayState = false;
|
||||
BUTTON btn;
|
||||
float rotaSpeed = 0.02 * PI; //virtual fan's rotating speed,
|
||||
float rotaPosition = 0; //motor position
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
GPIO.pinMode(relayPin, GPIO.OUTPUT);
|
||||
btn = new BUTTON(90, height - 90, 50, 30); //define the button
|
||||
btn.setBgColor(0, 255, 0); //set button color
|
||||
btn.setText("OFF"); //set button text
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
titleAndSiteInfo(); //title and site information
|
||||
|
||||
skey.keyScan(); //key scan
|
||||
if (skey.isPressed) { //key is pressed?
|
||||
relayAction();
|
||||
}
|
||||
textAlign(RIGHT, CENTER);
|
||||
text("RelayState: ", btn.x, btn.y+btn.h/2);
|
||||
btn.create(); //create the button
|
||||
if (relayState) {
|
||||
rotaPosition += rotaSpeed;
|
||||
}
|
||||
if (rotaPosition >= 2*PI) {
|
||||
rotaPosition = 0;
|
||||
}
|
||||
drawFan(rotaPosition); //show the virtual fan in Display window
|
||||
}
|
||||
//Draw a clover fan according to the stating angle
|
||||
void drawFan(float angle) {
|
||||
constrain(angle, 0, 2*PI);
|
||||
fill(0);
|
||||
for (int i=0; i<3; i++) {
|
||||
arc(width/2, height/2, 200, 200, 2*i*PI/3+angle, (2*i+0.3)*PI/3+angle, PIE);
|
||||
}
|
||||
fill(0);
|
||||
ellipse(width/2, height/2, 30, 30);
|
||||
fill(128);
|
||||
ellipse(width/2, height/2, 15, 15);
|
||||
}
|
||||
void relayAction() {
|
||||
if (relayState) {
|
||||
GPIO.digitalWrite(relayPin, GPIO.LOW);
|
||||
relayState = false;
|
||||
btn.setBgColor(255, 0, 0);
|
||||
btn.setText("OFF");
|
||||
} else {
|
||||
GPIO.digitalWrite(relayPin, GPIO.HIGH);
|
||||
relayState = true;
|
||||
btn.setBgColor(0, 255, 0);
|
||||
btn.setText("ON");
|
||||
}
|
||||
}
|
||||
void mousePressed() {
|
||||
if ((mouseY< btn.y+btn.h) && (mouseY>btn.y)
|
||||
&& (mouseX< btn.x+btn.w) && (mouseX>btn.x)) { // the mouse click the button
|
||||
relayAction();
|
||||
}
|
||||
}
|
||||
|
||||
void titleAndSiteInfo() {
|
||||
fill(0);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textSize(40); //set text size
|
||||
text("Relay & Motor", width / 2, 40); //title
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20); //site
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*****************************************************
|
||||
* Filename : BUTTON
|
||||
* Description : class BUTTON
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/22
|
||||
*****************************************************/
|
||||
class BUTTON {
|
||||
public int x, y, w, h;
|
||||
public String txt;
|
||||
private int bgr, bgg, bgb;
|
||||
private int tr, tg, tb;
|
||||
public BUTTON(int ix, int iy, int iw, int ih) {
|
||||
setPosition(ix, iy);
|
||||
setSize(iw, ih);
|
||||
setText("BTN");
|
||||
setBgColor(0, 0, 0);
|
||||
setTextColor(255,255,255);
|
||||
}
|
||||
public void create() {
|
||||
pushMatrix();
|
||||
translate(x,y);
|
||||
fill(bgr, bgg, bgb);
|
||||
rect(0, 0, w, h);
|
||||
fill(tr, tg, tb);
|
||||
textSize(min(w,h)/2);
|
||||
textAlign(CENTER, CENTER);
|
||||
text(txt, w/2, h/2);
|
||||
popMatrix();
|
||||
}
|
||||
public void setBgColor(int ir, int ig, int ib) {
|
||||
bgr = ir;
|
||||
bgg = ig;
|
||||
bgb = ib;
|
||||
}
|
||||
public void setText(String str) {
|
||||
txt = str;
|
||||
}
|
||||
public void setTextColor(int ir, int ig, int ib) {
|
||||
tr = ir;
|
||||
tg = ig;
|
||||
tb = ib;
|
||||
}
|
||||
public void setSize(int iw, int ih) {
|
||||
w = iw;
|
||||
h = ih;
|
||||
}
|
||||
public void setPosition(int ix, int iy) {
|
||||
x= ix;
|
||||
y = iy;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*****************************************************
|
||||
* Filename : Sketch_16_1_1_SteppingMotor
|
||||
* Description : Control the stepping motor
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/09/05
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
int[] pins = {18, 23, 24, 25}; //connect to motor phase A,B,C,D pins
|
||||
BUTTON btn; //BUTTON Object, For controlling the direction of motor
|
||||
SteppingMotor m = new SteppingMotor(pins);
|
||||
float rotaSpeed = 0, rotaPosition = 0; //motor speed
|
||||
boolean isMotorRun = true; //motor run/stop flag
|
||||
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
btn = new BUTTON(45, height - 90, 50, 30); //define the button
|
||||
btn.setBgColor(0, 255, 0); //set button color
|
||||
btn.setText("RUN"); //set button text
|
||||
m.motorStart(); //start motor thread
|
||||
rotaSpeed = 0.002 * PI; //virtual fan's rotating speed
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
titleAndSiteInfo(); //title and site information
|
||||
btn.create(); //create the button
|
||||
if (isMotorRun) { //motor is runnig
|
||||
fill(0);
|
||||
textAlign(LEFT,BOTTOM);
|
||||
textSize(20);
|
||||
if (m.dir == m.CW) {
|
||||
text("CW",btn.x,btn.y); //text "CW "
|
||||
rotaPosition+=rotaSpeed;
|
||||
if (rotaPosition>=TWO_PI) {
|
||||
rotaPosition = 0;
|
||||
}
|
||||
} else if (m.dir == m.CCW) {
|
||||
text("CCW",btn.x,btn.y); //text "CCW"
|
||||
rotaPosition-=rotaSpeed;
|
||||
if (rotaPosition<=0) {
|
||||
rotaPosition = TWO_PI;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m.steps<=0) { //if motor has stopped,
|
||||
if (m.dir == m.CCW) { //change the direction ,restart.
|
||||
m.moveSteps(m.CW, 1, 512);
|
||||
} else if (m.dir == m.CW) {
|
||||
m.moveSteps(m.CCW, 1, 512);
|
||||
}
|
||||
}
|
||||
drawFan(rotaPosition); //show the virtual fan in Display window
|
||||
}
|
||||
//Draw a clover fan according to the stating angle
|
||||
void drawFan(float angle) {
|
||||
constrain(angle, 0, 2*PI);
|
||||
fill(0);
|
||||
for (int i=0; i<3; i++) {
|
||||
arc(width/2, height/2, 200, 200, 2*i*PI/3+angle, (2*i+0.3)*PI/3+angle, PIE);
|
||||
}
|
||||
fill(0);
|
||||
ellipse(width/2, height/2, 30, 30);
|
||||
fill(128);
|
||||
ellipse(width/2, height/2, 15, 15);
|
||||
}
|
||||
|
||||
void exit() {
|
||||
m.motorStop();
|
||||
println("exit");
|
||||
System.exit(0);
|
||||
}
|
||||
void mousePressed() {
|
||||
if ((mouseY< btn.y+btn.h) && (mouseY>btn.y)
|
||||
&& (mouseX< btn.x+btn.w) && (mouseX>btn.x)) { // the mouse click the button
|
||||
if (isMotorRun) {
|
||||
isMotorRun = false;
|
||||
btn.setBgColor(255, 0, 0);
|
||||
btn.setText("STOP");
|
||||
m.motorStop();
|
||||
} else {
|
||||
isMotorRun = true;
|
||||
btn.setBgColor(0, 255, 0);
|
||||
btn.setText("RUN");
|
||||
m.motorRestart();
|
||||
}
|
||||
}
|
||||
}
|
||||
void titleAndSiteInfo() {
|
||||
fill(0);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textSize(40); //set text size
|
||||
text("Motor", width / 2, 40); //title
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20); //site
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*****************************************************
|
||||
* Filename : SteppingMotor
|
||||
* Description : class SteppingMotor
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/31
|
||||
*****************************************************/
|
||||
|
||||
class SteppingMotor {
|
||||
|
||||
final int[] CWStep = {0x01, 0x02, 0x04, 0x08}; //4 phase 4 steps power supply CW
|
||||
final int[] CCWStep = {0x08, 0x04, 0x02, 0x01}; //4 phase 4 steps power supply CCW
|
||||
final int CW = 1, CCW=2;
|
||||
int[] motorPins; //define pins connected to four phase ABCD of stepping motor
|
||||
boolean isDisable = false;
|
||||
int dir= CCW, ms=1, steps=-1;
|
||||
myThread mt = new myThread();
|
||||
Thread t = new Thread(mt);
|
||||
public SteppingMotor(int[] mPins) {
|
||||
motorPins = mPins;
|
||||
for (int i=0; i<4; i++) {
|
||||
GPIO.pinMode(motorPins[i], GPIO.OUTPUT);
|
||||
}
|
||||
}
|
||||
public void motorStart() {
|
||||
t.start();
|
||||
}
|
||||
//continuos rotation function,the parameter steps spectfies the rotation steps,
|
||||
//every four step is a steps(period)
|
||||
public void moveSteps(int idir, int ims, int isteps) {
|
||||
dir= idir;
|
||||
ms=ims;
|
||||
steps=isteps;
|
||||
motorRestart();
|
||||
}
|
||||
//used to motor stop rotating
|
||||
public void motorStop() {
|
||||
isDisable = true;
|
||||
for (int i=0; i<4; i++) {
|
||||
GPIO.digitalWrite(motorPins[i], GPIO.LOW);
|
||||
}
|
||||
}
|
||||
public void motorRestart() {
|
||||
isDisable = false;
|
||||
synchronized(t) {
|
||||
try {
|
||||
t.notifyAll();
|
||||
}
|
||||
catch(Exception e) {
|
||||
println(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
//It's same to moveOnePeriod()
|
||||
public void moveFourStep(int idir, int ims) {
|
||||
moveOnePeriod(idir, ims);
|
||||
}
|
||||
//drive the stepping motor to take four steps,four steps is a period
|
||||
public void moveOnePeriod(int idir, int ims) {
|
||||
if (isDisable) {
|
||||
println("Motor is disabled! Please enbale it!");
|
||||
motorStop();
|
||||
return;
|
||||
}
|
||||
for (int j=0; j<4; j++) { //cycle according to power supply order
|
||||
for (int i=0; i<4; i++) { //assign to each pin ,a total of 4 pins
|
||||
if (idir == CW) { //CW
|
||||
GPIO.digitalWrite(motorPins[i], (CWStep[j] == (1<<i) ? GPIO.HIGH :GPIO.LOW));
|
||||
} else if (idir == CCW) { //CCW
|
||||
GPIO.digitalWrite(motorPins[i], (CCWStep[j] == (1<<i) ? GPIO.HIGH :GPIO.LOW));
|
||||
}
|
||||
if (ims<1) { //the delay can't be less 3ms,
|
||||
ims = 1; //otherwise it will exceed speed limit of the motor
|
||||
}
|
||||
//delay(ms);
|
||||
try {
|
||||
Thread.sleep(ims);
|
||||
}
|
||||
catch(Exception e) {
|
||||
println(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
class myThread implements Runnable {
|
||||
public void run() {
|
||||
|
||||
while (true) {
|
||||
synchronized(t) {
|
||||
if (isDisable) {
|
||||
try {
|
||||
motorStop();
|
||||
t.wait();
|
||||
}
|
||||
catch(Exception e) {
|
||||
println("--->run:"+e);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (--steps>-1) {
|
||||
moveOnePeriod(dir, ms);
|
||||
} else {
|
||||
try {
|
||||
motorStop();
|
||||
}
|
||||
catch(Exception e) {
|
||||
println("--->run:"+e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*****************************************************
|
||||
* Filename : Calculator
|
||||
* Description : class Calculator
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/09/02
|
||||
*****************************************************/
|
||||
import java.math.BigDecimal;
|
||||
class Calculator {
|
||||
Keypad keypad;
|
||||
|
||||
double result=0; //Calculate result
|
||||
String txt = ""; //
|
||||
String contentStr = ""; //Display string
|
||||
char mark; //operate mark
|
||||
final int NUM=1, MARK=2, RESULT=3, BLANK = 4; //Current content
|
||||
int currentContent = BLANK; //
|
||||
boolean calcul_isStandBy = true; //Star and Clear
|
||||
char kkey = ' '; //the key value
|
||||
public Calculator(Keypad kp) {
|
||||
keypad = kp;
|
||||
}
|
||||
public void process() {
|
||||
kkey = kp.getKey();
|
||||
if (kkey != keypad.NO_KEY) { //if there is a key is pressed
|
||||
calcul_isStandBy = false;
|
||||
if ((kkey > 0x2F)&&(kkey < 0x3A)) { //key code is 0-9
|
||||
if (currentContent == RESULT) { //current Content is last results,clear
|
||||
txt="";
|
||||
txt+=kkey; //Store the key code
|
||||
currentContent=NUM;
|
||||
} else {
|
||||
txt+=kkey;
|
||||
currentContent=NUM;
|
||||
}
|
||||
} else if ((kkey == '+') || (kkey == '-')||(kkey == '*')||(kkey == '/')) {
|
||||
if (currentContent == RESULT) { //last results,Use it to make continuous calculations
|
||||
txt = ""+result;
|
||||
txt +=kkey;
|
||||
} else if (currentContent==MARK) { //change mark
|
||||
txt = txt.substring(0, txt.length()-1)+kkey;
|
||||
} else if (currentContent==BLANK) { //0 + mark
|
||||
txt+=("0"+kkey);
|
||||
} else {
|
||||
txt +=kkey;
|
||||
}
|
||||
currentContent=MARK;
|
||||
} else if (kkey == '=') { //if the key code is "="
|
||||
if (currentContent == RESULT) { //Keep last results
|
||||
txt+=("="+result);
|
||||
currentContent = RESULT;
|
||||
} else if (currentContent == BLANK) { //No active,keep standby
|
||||
calcul_isStandBy = true;
|
||||
currentContent = BLANK;
|
||||
} else {
|
||||
if (currentContent==MARK) { //if the last char is a MARK,delete it.
|
||||
txt = txt.substring(0, txt.length()-1);
|
||||
}
|
||||
if (txt.charAt(0) == '-') { //negative number,add "0" in start bit
|
||||
txt = "0".concat(txt);
|
||||
}
|
||||
result = parse(txt); //calculate the result
|
||||
txt+=("="+result);
|
||||
currentContent = RESULT;
|
||||
}
|
||||
} else if (kkey == 'C') { //clear
|
||||
cclear();
|
||||
}
|
||||
}
|
||||
if (calcul_isStandBy) {
|
||||
contentStr = "0";
|
||||
} else {
|
||||
contentStr = txt;
|
||||
}
|
||||
}
|
||||
public void cclear() { //Clear all datas, make calculator standby
|
||||
txt = "";
|
||||
calcul_isStandBy = true;
|
||||
result = 0;
|
||||
currentContent = BLANK;
|
||||
}
|
||||
public double parse(String content) { //parse processing
|
||||
int index = content.indexOf("+");
|
||||
if (index != -1) {
|
||||
BigDecimal b1 = new BigDecimal(parse(content.substring(0, index)));
|
||||
BigDecimal b2 = new BigDecimal(parse(content.substring(index+1)));
|
||||
return rround(b1.add(b2).doubleValue(),6);
|
||||
//return parse(content.substring(0, index)) + parse(content.substring(index+1));
|
||||
}
|
||||
index = content.lastIndexOf("-");
|
||||
if (index != -1) {
|
||||
BigDecimal b1 = new BigDecimal(parse(content.substring(0, index)));
|
||||
BigDecimal b2 = new BigDecimal(parse(content.substring(index+1)));
|
||||
return rround(b1.subtract(b2).doubleValue(),6);
|
||||
//return parse(content.substring(0, index)) - parse(content.substring(index+1));
|
||||
}
|
||||
index = content.indexOf("*");
|
||||
if (index != -1) {
|
||||
//println("* : "+content.substring(0, index) +" " + content.substring(index+1));
|
||||
BigDecimal b1 = new BigDecimal(parse(content.substring(0, index)));
|
||||
BigDecimal b2 = new BigDecimal(parse(content.substring(index+1)));
|
||||
return rround(b1.multiply(b2).doubleValue(),6);
|
||||
//return parse(content.substring(0, index)) * parse(content.substring(index+1));
|
||||
}
|
||||
index = content.lastIndexOf("/");
|
||||
if (index != -1) {
|
||||
//println("/ : "+content.substring(0, index) +" " + content.substring(index+1));
|
||||
BigDecimal b1 = new BigDecimal(parse(content.substring(0, index)));
|
||||
BigDecimal b2 = new BigDecimal(parse(content.substring(index+1)));
|
||||
return b1.divide(b2,6,BigDecimal.ROUND_HALF_UP).doubleValue();
|
||||
//return parse(content.substring(0, index)) / parse(content.substring(index+1));
|
||||
}
|
||||
Double result = 0d;
|
||||
//try {
|
||||
result = Double.parseDouble(content);
|
||||
//}
|
||||
//catch(Exception e) {
|
||||
// println(e+" \n txt: "+txt);
|
||||
//}
|
||||
//println("result: "+result);
|
||||
return result;
|
||||
}
|
||||
public double rround(double d,int len){ //rounding
|
||||
BigDecimal b1 = new BigDecimal(d);
|
||||
BigDecimal b2 = new BigDecimal(1);
|
||||
return b1.divide(b2,len,BigDecimal.ROUND_HALF_UP).doubleValue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*****************************************************
|
||||
* Filename : drawKeypad
|
||||
* Description : function drawKeypad
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/09/02
|
||||
*****************************************************/
|
||||
|
||||
final int gap =10;
|
||||
final int kSize = 50;
|
||||
final int kpSize = kSize*4+3*gap+gap*4;
|
||||
boolean keyIsPressed = false;
|
||||
int changeColorCnt = 0;
|
||||
int changeKeyCode = 0;
|
||||
void drawKeypad(int x, int y) {
|
||||
pushMatrix();
|
||||
translate(x, y);
|
||||
noStroke();
|
||||
fill(0);
|
||||
rect(0, 0, kpSize, kpSize, 10);
|
||||
|
||||
strokeWeight(4);
|
||||
stroke(255);
|
||||
fill(0);
|
||||
rect(gap, gap, kpSize-2*gap, kpSize-2*gap, 10);
|
||||
|
||||
strokeWeight(4);
|
||||
stroke(255);
|
||||
//fill(0,255,0);
|
||||
textSize(40);
|
||||
textAlign(CENTER, CENTER);
|
||||
for (int i=0; i<4; i++) {
|
||||
for (int j=0; j<4; j++) {
|
||||
if (((i<3)&&(j<3))||((i==3)&&(j==1))) { //blue and red
|
||||
fill(64, 64, 255);
|
||||
} else {
|
||||
fill(255, 64, 64);
|
||||
}
|
||||
if (cc.kkey == keys[4*i+j]) { //if any key is pressed,fill in green
|
||||
changeKeyCode = 4*i+j;
|
||||
fill(64, 255, 64);
|
||||
keyIsPressed = true;
|
||||
changeColorCnt = 0;
|
||||
} else if (keyIsPressed && (changeKeyCode == 4*i+j)) { //Keep green for some time
|
||||
changeColorCnt ++ ;
|
||||
if (changeColorCnt>20) {
|
||||
changeColorCnt = 0;
|
||||
keyIsPressed = false;
|
||||
}
|
||||
fill(64, 255, 64);
|
||||
}
|
||||
rect(2*gap+j*(kSize+gap), 2*gap+i*(kSize+gap), kSize, kSize, 5); //draw key
|
||||
fill(255); //draw key code of key
|
||||
text(keys[4*i+j], (2*gap+j*(kSize+gap)+kSize/2), (2*gap+i*(kSize+gap)+kSize/2));
|
||||
}
|
||||
}
|
||||
popMatrix();
|
||||
}
|
||||
|
||||
void drawDisplay(String content) {
|
||||
stroke(0);
|
||||
strokeWeight(4);
|
||||
fill(255);
|
||||
rect(0, 0, width, 50); //Display area
|
||||
fill(0);
|
||||
textSize(40);
|
||||
textAlign(RIGHT, TOP);
|
||||
text(content, width-5, 5); //Display content
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*****************************************************
|
||||
* Filename : Key
|
||||
* Description : class Key
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/09/02
|
||||
*****************************************************/
|
||||
|
||||
//class Key:Define some of the properties of Key
|
||||
class Key {
|
||||
final char NO_KEY = '\0';
|
||||
//Defines the four states of Key
|
||||
final int IDLE = 0,
|
||||
PRESSED = 1,
|
||||
HOLD = 2,
|
||||
RELEASED = 3;
|
||||
//define OPEN and CLOSED
|
||||
final int OPEN = 0,
|
||||
CLOSED = 1;
|
||||
char kchar;
|
||||
int kstate, kcode;
|
||||
boolean stateChanged;
|
||||
//constructor
|
||||
public Key() {
|
||||
kchar = NO_KEY;
|
||||
kstate = IDLE;
|
||||
kcode = -1;
|
||||
stateChanged = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
/*****************************************************
|
||||
* Filename : Keypad
|
||||
* Description : class Keypad
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/09/02
|
||||
*****************************************************/
|
||||
|
||||
class Keypad {
|
||||
final char NO_KEY = '\0';
|
||||
final int IDLE = 0,
|
||||
PRESSED = 1,
|
||||
HOLD = 2,
|
||||
RELEASED = 3;
|
||||
//define OPEN and CLOSED
|
||||
final int OPEN = 0,
|
||||
CLOSED = 1;
|
||||
final int LIST_MAX = 10, //Max number of keys on the active list.
|
||||
MAPSIZE = 10;//MAPSIZE is the number of rows (times 16 columns)
|
||||
int[] bitMap = new int[MAPSIZE];
|
||||
Key[] key = new Key[LIST_MAX];
|
||||
int holdTime = 500, //key hold time
|
||||
holdTimer = 0;
|
||||
int[] rowPins, colPins;
|
||||
int numRows, numCols;
|
||||
char[] keymap;
|
||||
int debounceTime = 10; //10ms
|
||||
long startTime = 0;
|
||||
public Keypad(char[] usrKeyMap, int[] row_Pins, int[] col_Pins) {
|
||||
keymap = usrKeyMap;
|
||||
rowPins = row_Pins;
|
||||
colPins = col_Pins;
|
||||
numRows = rowPins.length;
|
||||
numCols = colPins.length;
|
||||
for (int i=0; i<LIST_MAX; i++) {
|
||||
key[i] = new Key();
|
||||
}
|
||||
setPinMode();
|
||||
}
|
||||
// Returns a single key only. Retained for backwards compatibility.
|
||||
public char getKey() {
|
||||
if (getKeys() && key[0].stateChanged && (key[0].kstate==PRESSED)) {
|
||||
return key[0].kchar;
|
||||
}
|
||||
return NO_KEY;
|
||||
}
|
||||
public boolean getKeys() {
|
||||
boolean keyActivity = false;
|
||||
//Limit how often the keypad is scanned.
|
||||
if ((millis() - startTime) > debounceTime) {
|
||||
scanKeys();
|
||||
keyActivity = updateList();
|
||||
startTime = millis();
|
||||
}
|
||||
return keyActivity;
|
||||
}
|
||||
//set pins for input/output
|
||||
void setPinMode() {
|
||||
for (int i=0; i<numRows; i++) {
|
||||
GPIO.pinMode(rowPins[i], GPIO.INPUT);
|
||||
}
|
||||
for (int i=0; i<numCols; i++) {
|
||||
GPIO.pinMode(colPins[i], GPIO.OUTPUT);
|
||||
}
|
||||
}
|
||||
//Hardware scan ,the result store in bitMap
|
||||
void scanKeys() {
|
||||
//for (int i=0; i<numRows; i++) {
|
||||
// println("pinMode start."+i+" time:"+millis());
|
||||
// GPIO.pinMode(rowPins[i], GPIO.INPUT);
|
||||
// println("pinMode end."+i+" time:"+millis());
|
||||
//}
|
||||
//bitMap stores ALL the keys that are being pressed.
|
||||
for (int i=0; i<numCols; i++) {
|
||||
//GPIO.pinMode(colPins[i], GPIO.OUTPUT);
|
||||
GPIO.digitalWrite(colPins[i], GPIO.LOW);// Begin column pulse output.
|
||||
for (int j=0; j<numRows; j++) {// keypress is active low so invert to high.
|
||||
bitMap[j] = bitWrite(bitMap[j], i, (~GPIO.digitalRead(rowPins[j])&0x01));
|
||||
}
|
||||
GPIO.digitalWrite(colPins[i], GPIO.HIGH);
|
||||
//GPIO.pinMode(colPins[i], GPIO.INPUT);
|
||||
}
|
||||
}
|
||||
// Manage the list without rearranging the keys. Returns true if any keys on the list changed state.
|
||||
boolean updateList() {
|
||||
boolean anyActivity = false;
|
||||
// Delete any IDLE keys
|
||||
for (int i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].kstate == IDLE) {
|
||||
key[i].kchar = NO_KEY;
|
||||
key[i].kcode = -1;
|
||||
key[i].stateChanged = false ;
|
||||
}
|
||||
}
|
||||
// Add new keys to empty slots in the key list.
|
||||
for (int r=0; r<numRows; r++) {
|
||||
for (int c=0; c<numCols; c++) {
|
||||
boolean button = bitRead(bitMap[r], c);
|
||||
char keyChar = keymap[r * numCols +c];
|
||||
int keycode = r * numCols +c;
|
||||
int idx = findInList(keycode);
|
||||
// Key is already on the list so set its next state.
|
||||
if (idx > -1) {
|
||||
nextKeyState(idx, button);
|
||||
}
|
||||
// Key is NOT on the list so add it.
|
||||
if ((idx == -1)&& button) {
|
||||
for (int i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].kchar == NO_KEY) {// Find an empty slot or don't add key to list.
|
||||
key[i].kchar = keyChar;
|
||||
key[i].kcode = keycode;
|
||||
key[i].kstate = IDLE; // Keys NOT on the list have an initial state of IDLE.
|
||||
nextKeyState(i, button);
|
||||
break;// Don't fill all the empty slots with the same key.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Report if the user changed the state of any key.
|
||||
for (int i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].stateChanged) {
|
||||
anyActivity = true;
|
||||
}
|
||||
}
|
||||
return anyActivity;
|
||||
}
|
||||
// This function is a state machine but is also used for debouncing the keys.
|
||||
private void nextKeyState(int idx, boolean button) {
|
||||
key[idx].stateChanged = false;
|
||||
switch (key[idx].kstate) {
|
||||
case IDLE:
|
||||
if (button) {
|
||||
transitionTo (idx, PRESSED);
|
||||
holdTimer = millis();
|
||||
} // Get ready for next HOLD state.
|
||||
break;
|
||||
case PRESSED:
|
||||
if ((millis()-holdTimer)>holdTime) // Waiting for a key HOLD...
|
||||
transitionTo (idx, HOLD);
|
||||
else if (!button) // or for a key to be RELEASED.
|
||||
transitionTo (idx, RELEASED);
|
||||
break;
|
||||
case HOLD:
|
||||
if (!button) {
|
||||
transitionTo (idx, RELEASED);
|
||||
}
|
||||
break;
|
||||
case RELEASED:
|
||||
transitionTo (idx, IDLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
private void transitionTo(int idx, int nextState) {
|
||||
key[idx].kstate = nextState;
|
||||
key[idx].stateChanged = true;
|
||||
}
|
||||
// Search by code for a key in the list of active keys.
|
||||
// Returns -1 if not found or the index into the list of active keys.
|
||||
private int findInList(int keycode) {
|
||||
for (int i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].kcode == keycode) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public void setDebounceTime(int ms) {
|
||||
debounceTime = ms;
|
||||
}
|
||||
public void setHoldTime(int ms) {
|
||||
holdTime = ms;
|
||||
}
|
||||
public boolean isPressed(char keyChar) {
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if ( key[i].kchar == keyChar ) {
|
||||
if ( (key[i].kstate == PRESSED) && key[i].stateChanged )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false; // Not pressed.
|
||||
}
|
||||
public char waitForKey() {
|
||||
char waitKey = NO_KEY;
|
||||
while ( (waitKey = getKey()) == NO_KEY ); // Block everything while waiting for a keypress.
|
||||
return waitKey;
|
||||
}
|
||||
|
||||
// Backwards compatibility function.
|
||||
public int getState() {
|
||||
return key[0].kstate;
|
||||
}
|
||||
// The end user can test for any changes in state before deciding
|
||||
// if any variables, etc. needs to be updated in their code.
|
||||
boolean keyStateChanged() {
|
||||
return key[0].stateChanged;
|
||||
}
|
||||
private int bitWrite(int x, int n, int b) {
|
||||
if (b != 0) {
|
||||
x |= (1<<n);
|
||||
} else {
|
||||
x &= (~(1<<n));
|
||||
}
|
||||
return x;
|
||||
}
|
||||
private boolean bitRead(int x, int n) {
|
||||
if (((x>>n)&1) == 1) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*****************************************************
|
||||
* Filename : Sketch_17_1_1_MatrixKeypad
|
||||
* Description : Make a calculator using the keypad
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/09/02
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
final static char[] keys = { //key code
|
||||
'1', '2', '3', '+',
|
||||
'4', '5', '6', '-',
|
||||
'7', '8', '9', '*',
|
||||
'C', '0', '=', '/' };
|
||||
final int[] rowsPins = {18, 23, 24, 25}; //Connect to the row pinouts of the keypad
|
||||
final int[] colsPins = {10, 22, 27, 17}; //Connect to the column pinouts of the keypad
|
||||
Keypad kp = new Keypad(keys, rowsPins, colsPins); //class Object
|
||||
Calculator cc = new Calculator(kp); //class Object
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
}
|
||||
void draw() {
|
||||
background(102);
|
||||
titleAndSiteInfo(); //Tile and site information
|
||||
cc.process(); //Get key and processing
|
||||
drawDisplay(cc.contentStr); //Draw display area and content
|
||||
drawKeypad(width-kpSize, 70); //draw virtual Keypad
|
||||
}
|
||||
void titleAndSiteInfo() {
|
||||
fill(0);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textSize(40); //set text size
|
||||
text("Calculator", width / 4, 200); //title
|
||||
textSize(20);
|
||||
text("www.freenove.com", width / 4, height - 20); //site
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*****************************************************
|
||||
* Filename : Sketch_18_1_1_SenseLED
|
||||
* Description : Control the led by Infare motion sensor
|
||||
* auther : www.freenove.com
|
||||
* modification: 2016/08/22
|
||||
*****************************************************/
|
||||
import processing.io.*;
|
||||
|
||||
final int sensorPin = 17; //connect to sensor pin
|
||||
final int ledPin = 18; //connect to led pin
|
||||
void setup() {
|
||||
size(640,360); //window size
|
||||
GPIO.pinMode(sensorPin, GPIO.INPUT);
|
||||
GPIO.pinMode(ledPin, GPIO.OUTPUT);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(102);
|
||||
titleAndSiteInfo();
|
||||
//if read sensor for high level
|
||||
if (GPIO.digitalRead(sensorPin) == GPIO.HIGH) {
|
||||
GPIO.digitalWrite(ledPin, GPIO.HIGH); //led on
|
||||
fill(64,255,64); //fill in green
|
||||
} else {
|
||||
GPIO.digitalWrite(ledPin, GPIO.LOW); //led off
|
||||
fill(255); //fill in white
|
||||
}
|
||||
ellipse(width/2,height/2,height/2,height/2);
|
||||
}
|
||||
|
||||
void titleAndSiteInfo() {
|
||||
fill(0);
|
||||
textAlign(CENTER); //set the text centered
|
||||
textSize(40); //set text size
|
||||
text("SENSE LED", width / 2, 40); //title
|
||||
textSize(16);
|
||||
text("www.freenove.com", width / 2, height - 20); //site
|
||||
}
|
||||
Reference in New Issue
Block a user