.
.
转载于:
https://www.cnblogs.com/zhenqichai/p/raspberry-pi-control-GPIO-with-python.html
Python 控制树莓派 GPIO 输出:控制 LED 灯
树莓派 GPIO 控制输出的入门应该都是从控制 LED 灯开始的吧。
树莓派版本:Model 3B+
树莓派系统:Raspbian Stretch with desktop and recommended software,April 2019
准备一个 LED 灯,两个两头都为母的杜邦线。对照下图连接树莓派和 LED 灯,要求一个是地线(GND)连接灯的负极,一个有 GPIO + BCM 编号连接正极。我选择了 pin 号为 6 和 12 的两个引脚。你也可以选择别的,记得将之后的代码中 BCM 编号修改正确
在断电状态下连接。连接好的如下图,我的 LED 灯有正负极的提示,图中所示红色箭头指向的是正极,蓝色箭头是负极。如果你的 LED 灯是最简单的那种,长引脚就是正极,短的负极。
树莓派开机。
我装的树莓派系统已经满足所需要的环境,不需要额外下载。
你可以测试是否已经有该模块,在终端打开 Python3,然后尝试导入库: import RPi.GPIO as GPIO 。如果没有出现error,就表示已经有了,可以直接跳到下一步。
如果出现错误,则执行以下命令:
sudo apt-get update sudo apt-get install python3-rpi.gpio
按下图所示依次输入命令,观察。
GPIO.setmode() 有两种参数可以选择:可以使用 GPIO.BOARD 选项告诉库根据 GPIO 接口的引脚号引用信号,或者使用 Broadcom 芯片的信号编号( GPIO.setmode(GPIO.BCM) )。
在选择了模式之后,需要确定在程序中使用哪一个 GPIO 信号以及将家门用来作为输入还是输出:GPIO.setup(channel, direction)。我给的例子里是 GPIO.setup(18, GPIO.OUT) 。
后面两个命令控制灯的开关: GPIO.output(18, GPIO.HIGH) 和 GPIO.output(18, GPIO.LOW) 。
GPIO.cleanup() 用于重置 GPIO 接口,它把所有的 GPIO 引脚设置为低电平状态,所以没有多余的信号出现在界面上。在不使用改函数的情况下,如果试图配置一个已分配信号值的 GPIO 信号引脚,那么 RPi.GPIO 模块会产生一条警告信息。
然后我在树莓派上编写了下面这个代码让 LED 灯闪烁五次,保存在 Desktop,命名为 led.py。
#!/usr/bin/python3 import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BCM) GPIO.setup(18, GPIO.OUT) GPIO.output(18, GPIO.LOW) blinks = 0 print('开始闪烁') while (blinks < 5): GPIO.output(18, GPIO.HIGH) time.sleep(1.0) GPIO.output(18, GPIO.LOW) time.sleep(1.0) blinks = blinks + 1 GPIO.output(18, GPIO.LOW) GPIO.cleanup() print('结束闪烁')
演示结果:
也可以以通过 PWM 信号来达到让灯闪烁的效果。
#!/usr/bin/python3 import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) GPIO.setup(18, GPIO.OUT) blink = GPIO.PWM(18, 1) try: blink.start(50) while True: pass except KeyboardInterrupt: blink.stop() GPIO.cleanup()
start() 方法指定了占空比(从 1 到 100)。在开始 PWM 信号后,程序就可以解放出来做其他事情了。GPIO 18 会持续发送 PWM 信号,直到停止它。 blink = GPIO.PWM(18, 1) 指定了 PWM 信号以 1HZ 的频率发送,灯 1 秒闪烁一次。按 Control + C 中止闪烁。
《树莓派Python编程 入门与实战(第2版)》,人民邮电出版社
上述内容转载至:
作者:Zhenqi Chai
出处:https://www.cnblogs.com/zhenqichai/
版权声明:本文为作者原创文章,欢迎转载,但必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。
1.Tornado简介
Tornado一款使用 Python 编写的,相对简单的 非阻塞式 Web 服务器,它是非阻塞式服务器,而且速度相当快。得利于其 非阻塞的方式和对 epoll 的运用,Tornado 每秒可以处理数以千计的连接,因此 Tornado 是实时 Web 服务的一个 理想框架。
官方文档:http://www.tornadoweb.cn/documentation
整个文档就一个网页,把http服务器常用的功能都讲述了一遍,如果有编程基础,应该很快就能上手。
2.Tornado安装
方式1:pip 安装:
sudo pip install tornado
方式2:源代码安装:
wget https://pypi.python.org/packages/source/t/tornado/tornado-4.3.tar.gz
tar xvzf tornado-4.3.tar.gz
cd tornado-4.3
python setup.py build
sudo python setup.py install
3.HTML
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>树莓派Web控制中心</title>
<script src="static/js/jquery-3.2.1.min.js" type="text/javascript"></script>
<script src="static/js/bootstrap.min.js" type="text/javascript"></script>
<link href="static/css/bootstrap.css" rel="stylesheet" type="text/css" />
<link href="static/css/font-awesome-4.7.0/css/font-awesome.min.css" rel="stylesheet"
type="text/css" />
<style type="text/css">
.page-header { margin: 20px 0; border-bottom: 1px solid #eee; padding-bottom: 0; text-align: center; }
.btn-item { text-align: center; }
i { margin-right: 3px; display: inline-block; }
h1 { text-align: center; }
.tip { font-weight: bold; color: black; }
.lead { font-size: small; }
.gpio-item { text-align: center; }
.btn-gnd, .btn-gpio { padding: 10px 5px; margin-bottom: 5px; width: 100%; font-size: small; }
.gpio .row { margin-top: 5px; }
</style>
</head>
<body>
<div class="container">
<div class="page-header">
<h3>
树莓派Web控制中心</h3>
<p class="lead">
用于控制连接到树莓派的各种传感器
</p>
</div>
<div class="panel panel-default">
<div class="panel-heading">
设备</div>
<div class="panel-body">
<div class="row">
<div class="col-xs-3 btn-item">
</div>
<div class="col-xs-3 btn-item">
<a class="btn btn-danger btn-trigger"><i class="fa fa-power-off"></i>关机</a>
</div>
<div class="col-xs-3 btn-item">
<a class="btn btn-primary btn-trigger"><i class="fa fa-refresh"></i>重启</a>
</div>
<div class="col-xs-3 btn-item">
</div>
<script type="text/javascript">
var url = "/";
$(function () {
$(".btn-trigger").click(function () {
var text = $(this).text().replace(/ /g, "").replace(/\n/g, "").replace(/\r/g, "").replace(/\t/g, "");
var cmd = "";
switch (text) {
case "关机":
cmd = "sudo shutdown -h now";
break;
case "重启":
cmd = "sudo reboot";
break;
}
if (confirm("确定要执行该命令吗?")) {
$.ajax({
type: "POST",
url: url,
data: {
action: "run-shell-cmd",
cmd: cmd
},
success: function (result) {
//$(".tip").html(result);
}
});
}
});
});
</script>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
GPIO (蓝色->低电平,红色->高电平)</div>
<div class="panel-body gpio">
<div class="row">
<div class="col-xs-6 gpio-item">
左侧
</div>
<div class="col-xs-6 gpio-item">
右侧
</div>
</div>
<div class="row">
<div class="col-xs-6 gpio-item">
<button disabled="disabled" class="btn btn-info btn-gnd">
GND (9) 左05</button>
</div>
<div class="col-xs-6 gpio-item">
<button disabled="disabled" class="btn btn-info btn-gnd">
GND (6) 右03</button>
</div>
</div>
<div class="row">
<div class="col-xs-6 gpio-item">
<a class="btn btn-primary btn-gpio" pin="17">17 (11) 左06</a>
</div>
<div class="col-xs-6 gpio-item">
<a class="btn btn-primary btn-gpio" pin="18">18 (12) 右06</a>
</div>
</div>
<div class="row">
<div class="col-xs-6 gpio-item">
<a class="btn btn-primary btn-gpio" pin="27">27 (13) 左07</a>
</div>
<div class="col-xs-6 gpio-item">
<button disabled="disabled" class="btn btn-info btn-gnd">
GND (14) 右07</button>
</div>
</div>
<div class="row">
<div class="col-xs-6 gpio-item">
<a class="btn btn-primary btn-gpio" pin="22">22 (15) 左08</a>
</div>
<div class="col-xs-6 gpio-item">
<a class="btn btn-primary btn-gpio" pin="23">23 (16) 右08</a>
</div>
</div>
<div class="row">
<div class="col-xs-6 gpio-item">
<button disabled="disabled" class="btn btn-info btn-gnd">
GND (25) 左13</button>
</div>
<div class="col-xs-6 gpio-item">
<a class="btn btn-primary btn-gpio" pin="24">24 (18) 右09</a>
</div>
</div>
<div class="row">
<div class="col-xs-6 gpio-item">
<a class="btn btn-primary btn-gpio" pin="5">05 (29) 左15</a>
</div>
<div class="col-xs-6 gpio-item">
<button disabled="disabled" class="btn btn-info btn-gnd">
GND (20) 右10</button>
</div>
</div>
<div class="row">
<div class="col-xs-6 gpio-item">
<a class="btn btn-primary btn-gpio" pin="6">06 (31) 左16</a>
</div>
<div class="col-xs-6 gpio-item">
<a class="btn btn-primary btn-gpio" pin="25">25 (22) 右11</a>
</div>
</div>
<div class="row">
<div class="col-xs-6 gpio-item">
<a class="btn btn-primary btn-gpio" pin="13">13 (33) 左17</a>
</div>
<div class="col-xs-6 gpio-item">
<button disabled="disabled" class="btn btn-info btn-gnd">
GND (30) 右15</button>
</div>
</div>
<div class="row">
<div class="col-xs-6 gpio-item">
<a class="btn btn-primary btn-gpio" pin="19">19 (35) 左18</a>
</div>
<div class="col-xs-6 gpio-item">
<a class="btn btn-primary btn-gpio" pin="12">12 (32) 右16</a>
</div>
</div>
<div class="row">
<div class="col-xs-6 gpio-item">
<a class="btn btn-primary btn-gpio" pin="26">26 (37) 左19</a>
</div>
<div class="col-xs-6 gpio-item">
<button disabled="disabled" class="btn btn-info btn-gnd">
GND (34) 右17</button>
</div>
</div>
<div class="row">
<div class="col-xs-6 gpio-item">
<a class="btn btn-primary btn-gpio" pin="20">20 (37) 右19</a>
</div>
<div class="col-xs-6 gpio-item">
<a class="btn btn-primary btn-gpio" pin="16">16 (36) 右18</a>
</div>
</div>
<div class="row">
<div class="col-xs-6 gpio-item">
<button disabled="disabled" class="btn btn-info btn-gnd">
GND (39) 右20</button>
</div>
<div class="col-xs-6 gpio-item">
<a class="btn btn-primary btn-gpio" pin="21">21 (40) 右20</a>
</div>
</div>
<script type="text/javascript">
$(function () {
$(".btn-gpio").click(function () {
var gpio = $(this).attr("pin");
if ($(this).hasClass("btn-danger")) {
$(this).removeClass("btn-danger").addClass("btn-primary");
} else {
$(this).removeClass("btn-primary").addClass("btn-danger");
}
var status = $(this).hasClass("btn-danger") ? 1 : 0;
$.ajax({
type: "POST",
url: url,
data: {
action: "set-gpio-pin",
pin: gpio,
status: status
},
success: function (result) {
//$(".tip").html(result);
}
});
});
})
</script>
</div>
</div>
</div>
</body>
</html>
4.Python脚本
#coding: utf8
import sys
import RPi.GPIO as GPIO
import time
import os
import tornado.ioloop
import tornado.web
import tornado.httpserver
import tornado.options
from tornado.options import define,options
#初始化
def init():
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
#设置GPIO针脚电平输出
def SetPinStatus(pin,status):
GPIO.cleanup(int(pin))
GPIO.setup(int(pin),GPIO.OUT)
if(int(status)==0):
GPIO.output(int(pin),GPIO.LOW)
else:
GPIO.output(int(pin),GPIO.HIGH)
#路由处理
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.render("index.html")
def post(self):
init()
action=self.get_argument('action')
#设置GPIO针脚电平输出
if(action=="set-gpio-pin"):
pin = self.get_argument('pin')
status = self.get_argument('status')
SetPinStatus(pin,status)
self.write("true")
#执行shell脚本,如:关机,重启
elif(action=="run-shell-cmd"):
cmd = self.get_argument('cmd')
os.system(cmd)
if __name__ == '__main__':
#控制台输出响应结果,正式环境可以不开启
#tornado.options.parse_command_line()
settings={
"static_path":os.path.join(os.path.dirname(__file__),"static")
}
app = tornado.web.Application(
handlers=[
(r"/",IndexHandler),
(r"(apple-touch-icon\.png)",tornado.web.StaticFileHandler,dict(path=settings['static_path']))
],**settings)
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(8020)
tornado.ioloop.IOLoop.instance().start()
GPIO.cleanup()
5.示例
#coding: utf8
import sys
import RPi.GPIO as GPIO
import time
import os
# RuntimeError: Please set pin numbering mode using GPIO.setmode(GPIO.BOARD) or GPIO.setmode(GPIO.BCM)
GPIO.setmode(GPIO.BCM)
GPIO.setup(19,GPIO.OUT)
GPIO.output(19,GPIO.HIGH)
# GPIO.output(19,GPIO.LOW)
GPIO.setup(26,GPIO.OUT)
GPIO.output(26,GPIO.HIGH)
# GPIO.output(26,GPIO.LOW)
# GPIO.setup(channel, GPIO.OUT, initial=GPIO.HIGH)
C#地图坐标系的转换(WGS-84、GCJ-02、BD-09)
public class GPSChange
{
private const double pi = 3.14159265358979324;
private const double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
//克拉索天斯基椭球体参数值
private const double a = 6378245.0;
//第一偏心率
private const double ee = 0.00669342162296594323;
/// <summary>
/// GCJ-02转换BD-09
/// </summary>
/// <param name="gg_lat">纬度</param>
/// <param name="gg_lon">经度</param>
/// <returns></returns>
public static GPSPoint GCJ02_to_BD09(double gg_lat, double gg_lon)
{
GPSPoint point = new GPSPoint();
double x = gg_lon, y = gg_lat;
double z = Math.Sqrt(x * x + y * y) + 0.00002 * Math.Sin(y * x_pi);
double theta = Math.Atan2(y, x) + 0.000003 * Math.Cos(x * x_pi);
double bd_lon = z * Math.Cos(theta) + 0.0065;
double bd_lat = z * Math.Sin(theta) + 0.006;
point.SetLat(bd_lat);
point.SetLng(bd_lon);
return point;
}
/// <summary>
/// BD-09转换GCJ-02
/// </summary>
/// <param name="bd_lat">纬度</param>
/// <param name="bd_lon">经度</param>
/// <returns></returns>
public static GPSPoint BD09_to_GCJ02(double bd_lat, double bd_lon)
{
GPSPoint point = new GPSPoint();
double x = bd_lon - 0.0065, y = bd_lat - 0.006;
double z = Math.Sqrt(x * x + y * y) - 0.00002 * Math.Sin(y * x_pi);
double theta = Math.Atan2(y, x) - 0.000003 * Math.Cos(x * x_pi);
double gg_lon = z * Math.Cos(theta);
double gg_lat = z * Math.Sin(theta);
point.SetLat(gg_lat);
point.SetLng(gg_lon);
return point;
}
/// <summary>
/// WGS-84转换GCJ-02
/// </summary>
/// <param name="wgLat">纬度</param>
/// <param name="wgLon">经度</param>
/// <returns></returns>
public static GPSPoint WGS84_to_GCJ02(double wgLat, double wgLon)
{
GPSPoint point = new GPSPoint();
if (OutOfChina(wgLat, wgLon))
{
point.SetLat(wgLat);
point.SetLng(wgLon);
return point;
}
double dLat = TransformLat(wgLon - 105.0, wgLat - 35.0);
double dLon = TransformLon(wgLon - 105.0, wgLat - 35.0);
double radLat = wgLat / 180.0 * pi;
double magic = Math.Sin(radLat);
magic = 1 - ee * magic * magic;
double sqrtMagic = Math.Sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.Cos(radLat) * pi);
double lat = wgLat + dLat;
double lon = wgLon + dLon;
point.SetLat(lat);
point.SetLng(lon);
return point;
}
public static void Transform(double wgLat, double wgLon, double[] latlng)
{
if (OutOfChina(wgLat, wgLon))
{
latlng[0] = wgLat;
latlng[1] = wgLon;
return;
}
double dLat = TransformLat(wgLon - 105.0, wgLat - 35.0);
double dLon = TransformLon(wgLon - 105.0, wgLat - 35.0);
double radLat = wgLat / 180.0 * pi;
double magic = Math.Sin(radLat);
magic = 1 - ee * magic * magic;
double sqrtMagic = Math.Sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.Cos(radLat) * pi);
latlng[0] = wgLat + dLat;
latlng[1] = wgLon + dLon;
}
private static bool OutOfChina(double lat, double lon)
{
if (lon < 72.004 || lon > 137.8347)
return true;
if (lat < 0.8293 || lat > 55.8271)
return true;
return false;
}
private static double TransformLat(double x, double y)
{
double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.Sqrt(Math.Abs(x));
ret += (20.0 * Math.Sin(6.0 * x * pi) + 20.0 * Math.Sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.Sin(y * pi) + 40.0 * Math.Sin(y / 3.0 * pi)) * 2.0 / 3.0;
ret += (160.0 * Math.Sin(y / 12.0 * pi) + 320 * Math.Sin(y * pi / 30.0)) * 2.0 / 3.0;
return ret;
}
private static double TransformLon(double x, double y)
{
double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.Sqrt(Math.Abs(x));
ret += (20.0 * Math.Sin(6.0 * x * pi) + 20.0 * Math.Sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.Sin(x * pi) + 40.0 * Math.Sin(x / 3.0 * pi)) * 2.0 / 3.0;
ret += (150.0 * Math.Sin(x / 12.0 * pi) + 300.0 * Math.Sin(x / 30.0 * pi)) * 2.0 / 3.0;
return ret;
}
}
.
public class GPSPoint
{
private double lat;// 纬度
private double lng;// 经度
public GPSPoint()
{
}
public GPSPoint(double lng, double lat)
{
this.lng = lng;
this.lat = lat;
}
public double GetLat()
{
return lat;
}
public void SetLat(double lat)
{
this.lat = lat;
}
public double GetLng()
{
return lng;
}
public void SetLng(double lng)
{
this.lng = lng;
}
}
.
Java实现
package com.map.util;
public class GPSUtil {
public static double pi = 3.1415926535897932384626;
public static double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
public static double a = 6378245.0;
public static double ee = 0.00669342162296594323;
public static double transformLat(double x, double y) {
double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y
+ 0.2 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
return ret;
}
public static double transformLon(double x, double y) {
double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1
* Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0
* pi)) * 2.0 / 3.0;
return ret;
}
public static double[] transform(double lat, double lon) {
if (outOfChina(lat, lon)) {
return new double[]{lat,lon};
}
double dLat = transformLat(lon - 105.0, lat - 35.0);
double dLon = transformLon(lon - 105.0, lat - 35.0);
double radLat = lat / 180.0 * pi;
double magic = Math.sin(radLat);
magic = 1 - ee * magic * magic;
double sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
double mgLat = lat + dLat;
double mgLon = lon + dLon;
return new double[]{mgLat,mgLon};
}
public static boolean outOfChina(double lat, double lon) {
if (lon < 72.004 || lon > 137.8347)
return true;
if (lat < 0.8293 || lat > 55.8271)
return true;
return false;
}
/**
* 84 to 火星坐标系 (GCJ-02) World Geodetic System ==> Mars Geodetic System
*
* @param lat
* @param lon
* @return
*/
public static double[] gps84_To_Gcj02(double lat, double lon) {
if (outOfChina(lat, lon)) {
return new double[]{lat,lon};
}
double dLat = transformLat(lon - 105.0, lat - 35.0);
double dLon = transformLon(lon - 105.0, lat - 35.0);
double radLat = lat / 180.0 * pi;
double magic = Math.sin(radLat);
magic = 1 - ee * magic * magic;
double sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
double mgLat = lat + dLat;
double mgLon = lon + dLon;
return new double[]{mgLat, mgLon};
}
/**
* * 火星坐标系 (GCJ-02) to 84 * * @param lon * @param lat * @return
* */
public static double[] gcj02_To_Gps84(double lat, double lon) {
double[] gps = transform(lat, lon);
double lontitude = lon * 2 - gps[1];
double latitude = lat * 2 - gps[0];
return new double[]{latitude, lontitude};
}
/**
* 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 将 GCJ-02 坐标转换成 BD-09 坐标
*
* @param lat
* @param lon
*/
public static double[] gcj02_To_Bd09(double lat, double lon) {
double x = lon, y = lat;
double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
double tempLon = z * Math.cos(theta) + 0.0065;
double tempLat = z * Math.sin(theta) + 0.006;
double[] gps = {tempLat,tempLon};
return gps;
}
/**
* * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 * * 将 BD-09 坐标转换成GCJ-02 坐标 * * @param
* bd_lat * @param bd_lon * @return
*/
public static double[] bd09_To_Gcj02(double lat, double lon) {
double x = lon - 0.0065, y = lat - 0.006;
double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
double tempLon = z * Math.cos(theta);
double tempLat = z * Math.sin(theta);
double[] gps = {tempLat,tempLon};
return gps;
}
/**将gps84转为bd09
* @param lat
* @param lon
* @return
*/
public static double[] gps84_To_bd09(double lat,double lon){
double[] gcj02 = gps84_To_Gcj02(lat,lon);
double[] bd09 = gcj02_To_Bd09(gcj02[0],gcj02[1]);
return bd09;
}
public static double[] bd09_To_gps84(double lat,double lon){
double[] gcj02 = bd09_To_Gcj02(lat, lon);
double[] gps84 = gcj02_To_Gps84(gcj02[0], gcj02[1]);
//保留小数点后六位
gps84[0] = retain6(gps84[0]);
gps84[1] = retain6(gps84[1]);
return gps84;
}
/**保留小数点后六位
* @param num
* @return
*/
private static double retain6(double num){
String result = String .format("%.6f", num);
return Double.valueOf(result);
}
}
.
js实现
var GPS = {
PI : 3.14159265358979324,
x_pi : 3.14159265358979324 * 3000.0 / 180.0,
delta : function (lat, lon) {
// Krasovsky 1940
//
// a = 6378245.0, 1/f = 298.3
// b = a * (1 - f)
// ee = (a^2 - b^2) / a^2;
var a = 6378245.0; // a: 卫星椭球坐标投影到平面地图坐标系的投影因子。
var ee = 0.00669342162296594323; // ee: 椭球的偏心率。
var dLat = this.transformLat(lon - 105.0, lat - 35.0);
var dLon = this.transformLon(lon - 105.0, lat - 35.0);
var radLat = lat / 180.0 * this.PI;
var magic = Math.sin(radLat);
magic = 1 - ee * magic * magic;
var sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * this.PI);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * this.PI);
return {'lat': dLat, 'lon': dLon};
},
//WGS-84 to GCJ-02
gcj_encrypt : function (wgsLat, wgsLon) {
if (this.outOfChina(wgsLat, wgsLon))
return {'lat': wgsLat, 'lon': wgsLon};
var d = this.delta(wgsLat, wgsLon);
return {'lat' : wgsLat + d.lat,'lon' : wgsLon + d.lon};
},
//GCJ-02 to WGS-84
gcj_decrypt : function (gcjLat, gcjLon) {
if (this.outOfChina(gcjLat, gcjLon))
return {'lat': gcjLat, 'lon': gcjLon};
var d = this.delta(gcjLat, gcjLon);
return {'lat': gcjLat - d.lat, 'lon': gcjLon - d.lon};
},
//GCJ-02 to WGS-84 exactly
gcj_decrypt_exact : function (gcjLat, gcjLon) {
var initDelta = 0.01;
var threshold = 0.000000001;
var dLat = initDelta, dLon = initDelta;
var mLat = gcjLat - dLat, mLon = gcjLon - dLon;
var pLat = gcjLat + dLat, pLon = gcjLon + dLon;
var wgsLat, wgsLon, i = 0;
while (1) {
wgsLat = (mLat + pLat) / 2;
wgsLon = (mLon + pLon) / 2;
var tmp = this.gcj_encrypt(wgsLat, wgsLon)
dLat = tmp.lat - gcjLat;
dLon = tmp.lon - gcjLon;
if ((Math.abs(dLat) < threshold) && (Math.abs(dLon) < threshold))
break;
if (dLat > 0) pLat = wgsLat; else mLat = wgsLat;
if (dLon > 0) pLon = wgsLon; else mLon = wgsLon;
if (++i > 10000) break;
}
//console.log(i);
return {'lat': wgsLat, 'lon': wgsLon};
},
//GCJ-02 to BD-09
bd_encrypt : function (gcjLat, gcjLon) {
var x = gcjLon, y = gcjLat;
var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * this.x_pi);
var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * this.x_pi);
bdLon = z * Math.cos(theta) + 0.0065;
bdLat = z * Math.sin(theta) + 0.006;
return {'lat' : bdLat,'lon' : bdLon};
},
//BD-09 to GCJ-02
bd_decrypt : function (bdLat, bdLon) {
var x = bdLon - 0.0065, y = bdLat - 0.006;
var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * this.x_pi);
var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * this.x_pi);
var gcjLon = z * Math.cos(theta);
var gcjLat = z * Math.sin(theta);
return {'lat' : gcjLat, 'lon' : gcjLon};
},
//WGS-84 to Web mercator
//mercatorLat -> y mercatorLon -> x
mercator_encrypt : function(wgsLat, wgsLon) {
var x = wgsLon * 20037508.34 / 180.;
var y = Math.log(Math.tan((90. + wgsLat) * this.PI / 360.)) / (this.PI / 180.);
y = y * 20037508.34 / 180.;
return {'lat' : y, 'lon' : x};
/*
if ((Math.abs(wgsLon) > 180 || Math.abs(wgsLat) > 90))
return null;
var x = 6378137.0 * wgsLon * 0.017453292519943295;
var a = wgsLat * 0.017453292519943295;
var y = 3189068.5 * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a)));
return {'lat' : y, 'lon' : x};
//*/
},
// Web mercator to WGS-84
// mercatorLat -> y mercatorLon -> x
mercator_decrypt : function(mercatorLat, mercatorLon) {
var x = mercatorLon / 20037508.34 * 180.;
var y = mercatorLat / 20037508.34 * 180.;
y = 180 / this.PI * (2 * Math.atan(Math.exp(y * this.PI / 180.)) - this.PI / 2);
return {'lat' : y, 'lon' : x};
/*
if (Math.abs(mercatorLon) < 180 && Math.abs(mercatorLat) < 90)
return null;
if ((Math.abs(mercatorLon) > 20037508.3427892) || (Math.abs(mercatorLat) > 20037508.3427892))
return null;
var a = mercatorLon / 6378137.0 * 57.295779513082323;
var x = a - (Math.floor(((a + 180.0) / 360.0)) * 360.0);
var y = (1.5707963267948966 - (2.0 * Math.atan(Math.exp((-1.0 * mercatorLat) / 6378137.0)))) * 57.295779513082323;
return {'lat' : y, 'lon' : x};
//*/
},
// two point's distance
distance : function (latA, lonA, latB, lonB) {
var earthR = 6371000.;
var x = Math.cos(latA * this.PI / 180.) * Math.cos(latB * this.PI / 180.) * Math.cos((lonA - lonB) * this.PI / 180);
var y = Math.sin(latA * this.PI / 180.) * Math.sin(latB * this.PI / 180.);
var s = x + y;
if (s > 1) s = 1;
if (s < -1) s = -1;
var alpha = Math.acos(s);
var distance = alpha * earthR;
return distance;
},
outOfChina : function (lat, lon) {
if (lon < 72.004 || lon > 137.8347)
return true;
if (lat < 0.8293 || lat > 55.8271)
return true;
return false;
},
transformLat : function (x, y) {
var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(y * this.PI) + 40.0 * Math.sin(y / 3.0 * this.PI)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(y / 12.0 * this.PI) + 320 * Math.sin(y * this.PI / 30.0)) * 2.0 / 3.0;
return ret;
},
transformLon : function (x, y) {
var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(x * this.PI) + 40.0 * Math.sin(x / 3.0 * this.PI)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(x / 12.0 * this.PI) + 300.0 * Math.sin(x / 30.0 * this.PI)) * 2.0 / 3.0;
return ret;
}
};
.
centos 国内镜像站
.
http://mirrors.aliyun.com/centos/7/isos/x86_64/ 阿里云开源镜像
https://mirrors.cnnic.cn/centos/7/isos/x86_64/ 清华大学开源镜像
http://centos.ustc.edu.cn/centos/7/isos/x86_64/ 中国科学技术大学
http://ftp.sjtu.edu.cn/centos/7/isos/x86_64/ 上海交大
http://mirrors.163.com/centos/7/isos/x86_64/ 网易
http://mirrors.cn99.com/centos/7/isos/x86_64/ 网易开源镜像站
http://mirrors.sohu.com/centos/7/isos/x86_64/ 搜狐
.
1 初始化数据:
/usr/local/mysql/bin/mysqld --initialize-insecure --user=mysql --datadir=/opt/mysql/data --basedir=/opt/mysql
2 配置文件
vim /etc/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/mydata
socket=/tmp/mysql.sock
log_error=/var/log/mysql.log
user=mysql
port=6606
[mysql]
socket=/tmp/mysql.sock
作用:
1.影响服务端的启动
标签: [mysqld] [mysqld_safe] [server] ...
[mysqld]
basedir=/opt/mysql
datadir=/opt/mysql/data
user=mysql
socket=/tmp/mysql.sock
port=3306
server_id=6
2.影响客户端连接
标签: [client] [mysql] [mysqldump] ....
[mysql]
socket=/tmp/mysql.sock
=======================
3 多实例(3307 3308 3309)
3.1 创建相关目录
mkdir -p /data/330{7..9}/data
3.2 创建配置文件
cat>> /data/3307/my.cnf<<EOF
[mysqld]
basedir=/opt/mysql
datadir=/data/3307/data
user=mysql
socket=/data/3307/mysql.sock
port=3307
server_id=3307
EOF
cp /data/3307/my.cnf /data/3308
cp /data/3307/my.cnf /data/3309
sed -i 's#3307#3308#g' /data/3308/my.cnf
sed -i 's#3307#3309#g' /data/3309/my.cnf
3.3 初始化数据
mysqld --initialize-insecure --user=mysql --datadir=/data/3307/data --basedir=/opt/mysql
mysqld --initialize-insecure --user=mysql --datadir=/data/3308/data --basedir=/opt/mysql
mysqld --initialize-insecure --user=mysql --datadir=/data/3309/data --basedir=/opt/mysql
3.4 启动多实例
chown -R mysql.mysql /data/*
mysqld_safe --defaults-file=/data/3307/my.cnf &
mysqld_safe --defaults-file=/data/3308/my.cnf &
mysqld_safe --defaults-file=/data/3309/my.cnf &
4 测试
netstat -lnp|grep 330
mysql -S /data/3307/mysql.sock
mysql -S /data/3308/mysql.sock
mysql -S /data/3309/mysql.sock
5 systemd管理多实例
cat >> /etc/systemd/system/mysqld3307.service <<EOF
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/opt/mysql/bin/mysqld --defaults-file=/data/3307/my.cnf
LimitNOFILE = 5000
EOF
cp /etc/systemd/system/mysqld3307.service /etc/systemd/system/mysqld3308.service
cp /etc/systemd/system/mysqld3307.service /etc/systemd/system/mysqld3309.service
sed -i 's#3307#3308#g' /etc/systemd/system/mysqld3308.service
sed -i 's#3307#3309#g' /etc/systemd/system/mysqld3309.service
systemctl start mysqld3307
systemctl start mysqld3308
systemctl start mysqld3309
netstat -lnp|grep 330
systemctl stop mysqld3309
systemctl stop mysqld3308
systemctl stop mysqld3307
systemctl enable mysqld3307
systemctl enable mysqld3308
systemctl enable mysqld3309
6.忘记密码处理
mysqladmin -uroot -p password 123
select user,authentication_string,host from mysql.user;
1.停数据库
/etc/init.d/mysqld stop
2.启动数据库为无密码验证模式
mysqld_safe --skip-grant-tables --skip-networking &
update mysql.user set authentication_string=PASSWORD('456') where user='root' and host='localhost';
/etc/init.d/mysqld restart
[root@standby ~]# mysql -uroot -p123
[root@standby ~]# mysql -uroot -p456
7.数据类型和字符集
整型
int 最多存10位数字
-2^31 ~ 2^31-1
2^32 10位数 11
浮点
字符串类型
char 定长,存储数据效率较高,对于变化较多的字段,空间浪费较多
varchar 变长,存储时判断长度,存储会有额外开销,按需分配存储空间.
enum
时间
datetime
timestamp
date
time
SQL语句规范第五条:
1.少于10位的数字int ,大于10位数 char,例如手机号
2.char和varchar选择时,字符长度一定不变的可以使用char,可变的尽量使用varchar
在可变长度的存储时,将来使用不同的数据类型,对于索引树的高度是有影响的.
3.选择合适的数据类型
4.合适长度
转自:https://www.cnblogs.com/zhaijihai/p/10274860.html
备忘:
计算方式:(服务运行时间-服务不可用时间)/ 系统运行时间 X 100%
-----------------------
SLA:服务等级协议(简称:SLA,全称:service level agreement)。
是在一定开销下为保障服务的性能和可用性。
网站服务可用性SLA,9越多代表全年服务可用时间越长服务更可靠,停机时间越短,反之亦然。
互联网公司喊口号,我们今年一定要做到3个9、4个9的含义
1年 = 365天 = 8760小时
99.9 = 8760 * 0.1% = 8760 * 0.001 = 8.76小时
99.99 = 8760 * 0.0001 = 0.876小时 = 0.876 * 60 = 52.6分钟
99.999 = 8760 * 0.00001 = 0.0876小时 = 0.0876 * 60 = 5.26分钟
全年停机5.26分钟才能做到99.999%,即5个9
----------------------
1) 首先计算全年的总小时数:
365 * 24 = 8760 (时)
2) 3个9的标准
(365 * 24)* (1 - 99.9%) = 8760 (时) * 0.001= 8.76 (时)
3) 4个9的标准
(365 * 24)* (1 - 99.99%) = 8760 (时)* 0.0001 = 0.876 * 60 = 52.56 (分)
4) 5个9的标准
(365 * 24)* (1 - 99.999%) = 8760 (时) * 0.00001 = 0.0876 (时) * 60 = 5.256 (分)
windows:
连通性检查:
ping -4 主机名
获取主机名及MAC地址:
nbtstat -A IP
使用Excel时遇到---- 复制粘贴就卡死,CPU很高,记录下解决方法备忘:
打开Excel
或
在命令行中输入 Excel /safe 打开Excel
解决方法:
1. 文件功能界面 -> 选择“选项”
2.点击“加载项”功能
3.在管理功能框中,选择“COM 加载项” 并点击转到
4.清除列表中的所有复选框
5.关闭重新启动
.
一、QPS,每秒查询
QPS:Queries Per Second意思是“每秒查询率”,是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。
互联网中,作为域名系统服务器的机器的性能经常用每秒查询率来衡量。
二、TPS,每秒事务
TPS:是TransactionsPerSecond的缩写,也就是事务数/秒。它是软件测试结果的测量单位。一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数。
QPS vs TPS:QPS基本类似于TPS,但是不同的是,对于一个页面的一次访问,形成一个TPS;但一次页面请求,可能产生多次对服务器的请求,服务器对这些请求,就可计入“QPS”之中。如,访问一个页面会请求服务器2次,一次访问,产生一个“T”,产生2个“Q”。
三、RT,响应时间
响应时间:执行一个请求从开始到最后收到响应数据所花费的总体时间,即从客户端发起请求到收到服务器响应结果的时间。
响应时间RT(Response-time),是一个系统最重要的指标之一,它的数值大小直接反应了系统的快慢。
四、并发数
并发数是指系统同时能处理的请求数量,这个也是反应了系统的负载能力。
五、吞吐量
系统的吞吐量(承压能力)与request对CPU的消耗、外部接口、IO等等紧密关联。单个request 对CPU消耗越高,外部系统接口、IO速度越慢,系统吞吐能力越低,反之越高。
系统吞吐量几个重要参数:QPS(TPS)、并发数、响应时间。
QPS(TPS):(Query Per Second)每秒钟request/事务 数量
并发数: 系统同时处理的request/事务数
响应时间: 一般取平均响应时间
理解了上面三个要素的意义之后,就能推算出它们之间的关系:
QPS(TPS)= 并发数/平均响应时间
并发数 = QPS*平均响应时间
六、实际举例
我们通过一个实例来把上面几个概念串起来理解。按二八定律来看,如果每天 80% 的访问集中在 20% 的时间里,这 20% 时间就叫做峰值时间。
公式:( 总PV数 * 80% ) / ( 每天秒数 * 20% ) = 峰值时间每秒请求数(QPS)
机器:峰值时间每秒QPS / 单台机器的QPS = 需要的机器
1、每天300w PV 的在单台机器上,这台机器需要多少QPS?
( 3000000 * 0.8 ) / (86400 * 0.2 ) = 139 (QPS)
2、如果一台机器的QPS是58,需要几台机器来支持?
139 / 58 = 3
七、最佳线程数、QPS、RT
1、单线程QPS公式:QPS=1000ms/RT
对同一个系统而言,支持的线程数越多,QPS越高。假设一个RT是80ms,则可以很容易的计算出QPS,QPS = 1000/80 = 12.5
多线程场景,如果把服务端的线程数提升到2,那么整个系统的QPS则为 2*(1000/80) = 25, 可见QPS随着线程的增加而线性增长,那QPS上不去就加线程呗,听起来很有道理,公司也说的通,但是往往现实并非如此。
2、QPS和RT的真实关系
我们想象的QPS、RT关系如下,
实际的QPS、RT关系如下,
3、最佳线程数量
刚好消耗完服务器的瓶颈资源的临界线程数,公式如下
最佳线程数量=((线程等待时间+线程cpu时间)/线程cpu时间)* cpu数量
特性:
在达到最佳线程数的时候,线程数量继续递增,则QPS不变,而响应时间变长,持续递增线程数量,则QPS开始下降。
每个系统都有其最佳线程数量,但是不同状态下,最佳线程数量是会变化的。
瓶颈资源可以是CPU,可以是内存,可以是锁资源,IO资源:超过最佳线程数-导致资源的竞争,超过最佳线程数-响应时间递增。
————————————————
版权声明:本文为CSDN博主「技术大咖秀」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/shipfei_csdn/article/details/103225517
1)bit = 位:是二进制中的一位,是计算机表示数据的最小单位,也就是说是二进制中01中的一位
2)字节:byte = B = Byte = 字节 ,是计算机存储的最小单位 ,1byte = 1B = 1Byte = 1 字节 = 8bit
3)字符:字符>=字节,1个英文字母 = 1字节 = 8 bit, 1 个中文字符 = 2字节 = 16bit
1Byte=8bit,1KB=1024B,1MB=1024KB,1GB=1024MB,1TB=1024GB
在计算机/通讯行业中,计算数据传送速度也使用每秒传送公制数据量来计算
1 bit (b) = 0 or 1 = one binary digit 一个二进制位元
1 kilobit(kb)=10^3 bits = 1,000 bits 一千位元
1 Megabit(Mb)=10^6 bits = 1,000,000 bits 一百万位元
1 Gigabit(Gb)=10^9 bits = 1,000,000,000 bits 一万亿位元
根据进制规定,传送速度可以有两种表示方法 bps 和 Bps,但是他们是有严格区别。Bps中的 B 使用的是二进制系统中的Byte字节 ,bps中的 b 是十进制系统中的位元。
在我们常说的56K拨号,100M局域网都是bps计量,当用于软件下载时,下载工具一般又以Bps计算,所以它们之间有 8 bit=1 Byte 的换算关系,那么56Kbps拨号极限下载速度是 56Kbps/8=7KBps 每秒下载7K字节 。
在数据存储,容量计算中,一般又结合公制的进制和二进制的数据计算方法来计算
(二进制)
1 byte (B) = 8 bits (b) 字节=8个二进制位
1 Kilobyte(K/KB)=2^10 bytes=1,024 bytes 千字节
1 Megabyte(M/MB)=2^20 bytes=1,048,576 bytes 兆字节
1 Gigabyte(G/GB)=2^30 bytes=1,073,741,824 bytes 千兆字节
1 Terabyte(T/TB)=2^40 bytes=1,099,511,627,776 bytes吉字节
一些存储器厂家特别是硬盘厂家就更紧密结合十进制来计算,这就是为什么操作系统显示的容量与厂家标示的容量有些一些差异的原因 (十进制)
1 byte (B) = 8 bits (b)
1 Kilobyte (K / KB) = 10^3 bytes = 1,000 bytes
1 Megabyte (M / MB) = 10^6 bytes = 1,000,000 bytes
1 Gigabyte (G / GB) = 10^9 bytes = 1,000,000,000 bytes
1 Terabyte (T / TB) = 10^12 bytes = 1,000,000,000,000 bytes
因此
500g的硬盘,实际只有1000/1024*500=488g左右
.