Add Processing Sketchs
Add Processing Sketchs and Processing tutorial
This commit is contained in:
Binary file not shown.
@@ -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
|
||||
}
|
||||
@@ -4,8 +4,10 @@ References
|
||||
The references for this product includes the following folders and files:
|
||||
Datasheet Datasheet of electronic components and modules
|
||||
Code Code for Raspberry Pi
|
||||
Processing Sketches for Interacting with Processing projects
|
||||
Readme.txt Instructions
|
||||
Tutorial.pdf Tutorial
|
||||
Processing.pdf Tutorial for Interacting with Processing
|
||||
|
||||
You can click the green Clone or download button in this page, then click Download ZIP to get all these files in zip format. If you have any difficulties, you can send email to our support for help.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user