树莓派4B的入门操作
一、树莓派系统烧录
① 、准备一个8G以上的micro SD卡和读卡器,推荐使用class4以上的卡
② 、登录https://www.raspberrypi.org/downloads/获取系统安装。
③ 、将下载下来的zip压缩包进行解压
④ 、在Windows上使用etcher软件烧录,下载网站https://www.balena.io/etcher。
⑤ 、将TF卡插入到读卡器里面,插到电脑USB上,打开etcher进行烧录,如果失败,可以对TF卡进行格式化,在进行烧录。
二、无屏幕有线远程连接
① 、在TF烧写的系统的boot目录下,新建一个ssh文件。
② 、用网线将树莓派和电脑连接起来,打开电源,启动树莓派。
③ 、笔记本连接上无线网络,在电脑上右键wifi图标打开网络和共享中心>更改适配器设置,共享无线网络,如下图所示。
④ 、打开电脑cmd,输入ipconfig查看以太网配置器的IP。
⑤ 、输入arp -a查看树莓派IP地址,如下图所示。
⑥ 、打开安装好putty软件,界面如下,输入树莓派IP地址,点击确认。
⑦ 、进入以下界面,输入用户:pi,密码:raspberry,证明成功连接上树莓派
三、无屏幕无线远程连接
① 、在TF烧写的系统的boot目录下,新建一个ssh文件和一个wpa_supplicant.conf文件,wpa_supplicant.conf文件内容如下:
1 country=CN 2 3 ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev 4 5 update_config=1 6 7 8 9 network={ 10 11 ssid="WiFi-A" 12 13 psk="12345678" 14 15 key_mgmt=WPA-PSK 16 17 priority=1 18 19 } 20 21 22 23 network={ 24 25 ssid="WiFi-B" 26 27 psk="12345678" 28 29 key_mgmt=WPA-PSK 30 31 priority=2 32 33 scan_ssid=1 34 35 }
#ssid:网络的ssid
#psk:密码
#priority:连接优先级,数字越大优先级越高(不可以是负数)
#scan_ssid:连接隐藏WiFi时需要指定该值为1
② 、将TF烧写插入到树莓派上面,启动树莓派,自动连接上无线WiFi,同时电脑也连接上该WiFi。
③ 、通过手机热点连接的设备,查看树莓派IP地址或者直接在路由器后台中找到树莓派的IP地址或使用Advanced IP Scanner获取。
④ 、远程登录树莓派客户端很多,putty、xshell、手机端juiceSSH。以putty为例,安装好putty软件,打开,界面如下,输入树莓派IP地址,点击确认。
⑤ 、进入以下界面,证明成功连接上树莓派
四、Windows远程桌面连接
① 、树莓派和电脑必须连接同一网段,无线或者有线连接都可以
② 、打开电脑,win+r打开运行窗口,输入mstsc进入远程桌面连接,输入树莓派IP地址。如下图所示。
③ 、点击确认,输入树莓派用户名:pi,密码:raspberry,点击OK。如下图所示。
④ 、点击OK,进入树莓派桌面,如下图所示。
五、系统备份与恢复
注:需要有安装好系统的TF卡,下载win32DiskImager软件
① 、建立一个空白的.img文件。
② 、打开win32磁盘映像工具,选择含系统的TF卡
③ 、选择刚刚建立好的空.img文件,点击读取。
④ 、系统恢复,选择新的TF卡或格式化的TF卡,选择之前备份的.img镜像文件,点击写入。
六、无线WiFi上网配置
① 、有屏幕,打开树莓派右上角选择WiFi连接
② 、无屏幕,使用命令sudo nano
/etc/wpa_supplicant/wpa_supplicant.conf,进入配置。
③ 、在TF的boot目录中建立一个新的wpa_supplicant.conf文件,里面按照②中的方法进行设置。
七、开启SSH四种方法
① 、在SD卡boot目录中新建ssh
② 、开启系统,输入命令:sudo /etc/init.d/ssh start,回车
③ 、点击首选项
点击Interface栏,选择SSH为enable
④ 、输入命令:sudo raspi-config回车,选择5 interfacing options回车,再选择SSH,点击是,回车,点击finish。
八、开启VNC的三种方法
VNC是一款使用RFB协定的屏幕画面分享及远程操作软件
① 、开启系统,输入命令:vncserver回车,只能临时用,重启一次开一次。
② 、输入命令:sudo raspi-config,回车,选择5 Interfacing Options,回车,选择VNC,enable。
③ 、使用VNC-Viewer客户端,打开,输入树莓派IP地址,进入界面输入用户名和密码登录。
九、树莓派摄像头使用
① 、断电接上摄像头之后,启动树莓派,系统使能摄像头。执行命令:sudo raspi-config,界面如下:
② 、使用raspistill -o new.jpg拍照,查看命令xdg-open new.jpg。使用raspivid -o vv.h264 -t
10000s命令录制视频。
③ 、实现远程拍照控制及照片获取
简单网络获取实时照片实现,建立socket通信,树莓派用python写socket服务器,线程监听端口,Windows用java写socket客户端。客户端连接服务器后发送相关指令调用树莓派拍照程序进行拍照,然后把照片数据用byte格式传递给客户端,客户端进行有效接收,并显示。
其中启动按钮为启动socket客户端,测试按钮为测试连接状态,获取按钮为调用拍照指令,程序整体实现较简单,java客户端没有使用线程,所以会有卡顿现象。后续进会进一步调优。
树莓派python代码:
1 import os 2 3 import socketserver 4 5 class Sok(socketserver.BaseRequestHandler): 6 7 def handle(self): 8 9 while True: 10 11 try: 12 13 self.datax=self.request.recv(1024).decode("gbk") 14 15 if(self.datax==""):break 16 17 print(self.client_address,"-------",self.datax) 18 19 if self.datax=="1": 20 21 self.request.send("#start take a picture...".encode("gbk")) 22 23 os.system("raspistill -o new.jpg") 24 25 os.system("xdg-open new.jpg") 26 27 self.request.send("#finish,transmitting...".encode("gbk")) 28 29 f=open("new.jpg","rb") 30 31 f_size=os.stat("new.jpg").st_size 32 33 self.request.send(("#size:"+str(f_size)).encode("gbk")) 34 35 self.request.recv(100) 36 37 for lin in f: 38 39 self.request.send(lin) 40 41 if self.datax=="0": 42 43 self.request.send("#communication success...".encode("gbk")) 44 45 except Exception as e: 46 47 print("-----exception-----",e) 48 49 break 50 51 sock=socketserver.ThreadingTCPServer(("0.0.0.0",2351),Sok) 52 53 sock.serve_forever()
客户端使用java:
1 package camera; 2 import java.awt.Graphics; 3 import java.awt.Image; 4 import java.awt.Toolkit; 5 import java.awt.event.ActionEvent; 6 import java.awt.event.ActionListener; 7 import java.awt.event.WindowAdapter; 8 import java.awt.event.WindowEvent; 9 import java.io.DataInputStream; 10 import java.io.FileNotFoundException; 11 import java.io.FileOutputStream; 12 import java.io.IOException; 13 import java.io.InputStream; 14 import java.io.OutputStream; 15 import java.io.UnsupportedEncodingException; 16 import java.net.Socket; 17 import java.net.UnknownHostException; 18 import javax.swing.ImageIcon; 19 import javax.swing.JButton; 20 import javax.swing.JFrame; 21 import javax.swing.JLabel; 22 import javax.swing.JPanel; 23 24 25 class Main2 extends JFrame{ 26 JLabel jlde; 27 private Image image; //获取的图像 28 private Toolkit toolKit; //Toolkit对象,用于获取图像 29 private Socket sock; 30 private InputStream reader; 31 private OutputStream writer; 32 private boolean booxie; 33 private DataInputStream dis; 34 JLabel zt; 35 int sizex=0; 36 public Main2(){//构造函数 37 super("图片获取实现");//标题显示内容 38 this.setSize(600, 400);//页面大小 39 this.setResizable(false);//不可缩放 40 this.setLocationRelativeTo(null);//全屏居中居中显示 41 jlde=new JLabel(); 42 jlde.setBounds(0, 0,this.getWidth(), this.getWidth()); 43 this.add(jlde); 44 JButton qd=new JButton("启动"); 45 JButton cs=new JButton("测试"); 46 JButton hq=new JButton("获取"); 47 JPanel jp=new JPanel(); 48 zt = new JLabel(); 49 jp.add(qd); 50 jp.add(cs); 51 jp.add(hq); 52 jp.add(zt); 53 Imgben("lala.png");//初始图片显示 54 this.setIconImage(new ImageIcon("lala.png").getImage());//图标图片文件 55 this.add(jp,"South"); 56 this.setVisible(true);//显示界面 57 qd.addActionListener(new ActionListener(){//-------------------启动按钮监听,开启socket 58 @Override 59 public void actionPerformed(ActionEvent e) { 60 zt.setText("正在启动......."); 61 try { 62 63 64 sock=new Socket("192.168.43.243",2351); 65 writer=sock.getOutputStream();//获取输出流 66 reader=sock.getInputStream();//获取输入流 67 dis = new DataInputStream(sock.getInputStream());//包装输入流, 允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。 68 writer.write(("0").getBytes("GBK"));//发送确认信息 69 reads();//读数据 70 71 72 } catch (UnknownHostException e1) { 73 e1.printStackTrace(); 74 } catch (IOException e1) { 75 e1.printStackTrace(); 76 }}}); 77 cs.addActionListener(new ActionListener(){//------------------------测试是否连接成功 78 79 @Override 80 public void actionPerformed(ActionEvent e) { 81 try { 82 83 writer.write(("0").getBytes("GBK")); 84 reads(); 85 86 } catch (UnsupportedEncodingException e1) { 87 e1.printStackTrace(); 88 } catch (IOException e1) { 89 e1.printStackTrace(); 90 }}}); 91 hq.addActionListener(new ActionListener(){//-------------------获取图片按钮,点击可显示实时图片 92 @Override 93 public void actionPerformed(ActionEvent e) { 94 try { 95 zt.setText("开始获取......"); 96 writer.write(("1").getBytes("GBK"));//发送获取图片指令 97 reads(); 98 reads(); 99 writer.write(("3").getBytes("GBK"));//发送空的确认获取指令 100 String str= reads(); 101 sizex=Integer.parseInt(str.substring(str.indexOf("e")+2));//得到图片大小 102 reads();//读取图片数据 103 zt.setText(" 成功获取 *-* "); 104 Imgben("new.jpg");//显示获取的图片 105 106 } catch (UnsupportedEncodingException e1) { 107 e1.printStackTrace(); 108 } catch (IOException e1) { 109 e1.printStackTrace(); 110 }}}); 111 this.addWindowListener(new WindowAdapter() {//点击叉监听,完全退出程序 112 public void windowClosing(WindowEvent arg0) { 113 System.exit(0); 114 } 115 });} 116 public String reads() throws FileNotFoundException{ 117 String strread=""; 118 FileOutputStream fos=null; 119 if(sizex>0){//【 开始接收文件 】 120 fos = new FileOutputStream("new.jpg"); 121 byte[] bytes = new byte[1024]; 122 int length = 0; 123 int bensizej=0; 124 try { 125 while(( length = dis.read(bytes, 0, bytes.length)) != -1) { 126 bensizej+=length; 127 try { 128 fos.write(bytes, 0, length);//以追加的方式写数据 129 fos.flush(); 130 if(sizex<=bensizej) break;//获取完成 131 } catch (IOException e) { 132 e.printStackTrace(); 133 } }} catch (IOException e) { 134 e.printStackTrace();} 135 sizex=0; 136 bensizej=0; //清零计数 137 }else{ //【 开始接收普通数据 】 138 byte[] bu=new byte[1024]; 139 try { 140 reader.read(bu); 141 strread=(new String(bu,"GBK")).trim(); 142 System.out.println(strread); 143 zt.setText(strread); 144 } catch (Exception e) { 145 e.printStackTrace(); 146 }} 147 return strread;//返回读取的普通数据 148 } 149 150 //加载本地图片 151 public void Imgben(String imagePath){ 152 toolKit = Toolkit.getDefaultToolkit(); 153 repaint(); //重绘屏幕 154 image= toolKit.getImage(imagePath); 155 } 156 public void paint(Graphics g){ 157 super.paint(g); 158 if (image!=null){ 159 image.getScaledInstance(500, 500, Image.SCALE_DEFAULT); 160 ImageIcon ico=new ImageIcon(image); 161 ico.setImage(ico.getImage().getScaledInstance(600,370, Image.SCALE_DEFAULT)); 162 jlde.setIcon(ico); 163 }}} 164 165 public class Camera { 166 public static void main(String[] args) { 167 new Main2(); 168 } 169 170 }
十、使用Cron在启动时运行Python脚本
①、创建一个python脚本,使用命令cat /home/pi/Desktop/get.py来检查路径是否正确
② 、添加一个新的Cron,使用命令sudo crontab –e,如下图所示。
③ 、在底部添加@reboot python /home/pi/Desktop/get.py &
④ 、要保存这些更改,请单击“CTRL-X”,然后单击“Y”,最后单击“Return”。
⑤ 、重启树莓派,输入sudo reboot,这样脚本就随着树莓派启动而启动
⑥ 、要停止该脚本运行,需要使用ps aux | grep /home/pi/Desktop/get.py命令,得到以“root”开头的一个进程号,再使用sudo kill 1863命令结束该进程。
十一、使用systemd在启动时自动运行Python脚本
① 、使用“ systemd”,因为这似乎是启动自定义功能的推荐方式,许多Linux发行版都在采用它。
② 、在home/pi/建立一个python脚本,使用sudo nano /lib/systemd/system/myscript.service命令一个配置文件。添加内容如下:
1 [Unit] 2 Description=My Script Service 3 After=multi-user.target 4 5 [Service] 6 Type=idle 7 ExecStart=/usr/bin/python /home/pi/myscript.py 8 9 [Install] 10 WantedBy=multi-user.target
1 [Unit] 2 Description=My Script Service 3 After=multi-user.target 4 5 [Service] 6 Type=idle 7 ExecStart=/usr/bin/python /home/pi/myscript.py 8 9 [Install] 10 WantedBy=multi-user.target
使用using [CTRL-X], [Y] then [ENTER]保存退出。
③ 、为了将脚本的文本输出存储在日志文件中,您可以将ExecStart行更改为:
1 ExecStart=/usr/bin/python /home/pi/myscript.py > /home/pi/myscript.log 2>&1
④ 需要将单元文件上的权限设置为644,如:
1 sudo chmod 644 /lib/systemd/system/myscript.service
⑤ 、配置systemd,systemd在引导序列中启动它
1 sudo systemctl daemon-reload 2 sudo systemctl enable myscript.service
⑥ 、重启树莓派
1 sudo reboot
⑦ 、检查服务状态
1 sudo systemctl status myscript.service