Java树莓派案例

wen java案例 2

本文目录导读:

Java树莓派案例

  1. LED闪烁控制(GPIO基础)
  2. 温湿度传感器(DHT11/DHT22)
  3. 摄像头拍照 + 人脸检测
  4. Web服务器 + 远程控制
  5. 自动化监控系统
  6. 部署与运行
  7. 性能优化建议
  8. 故障排查

我来为您介绍几个Java在树莓派上的经典应用案例,从基础到进阶。

LED闪烁控制(GPIO基础)

硬件准备

  • 树莓派(任何型号)
  • LED灯 + 330Ω电阻
  • 面包板和跳线

完整代码示例

import com.pi4j.io.gpio.*;
public class LEDBlink {
    public static void main(String[] args) throws InterruptedException {
        // 创建GPIO控制器
        final GpioController gpio = GpioFactory.getInstance();
        // 配置GPIO 1号引脚(BCM编号)为输出
        final GpioPinDigitalOutput led = gpio.provisionDigitalOutputPin(
            RaspiPin.GPIO_01, "LED", PinState.LOW);
        System.out.println("LED闪烁程序开始...");
        // 闪烁10次
        for (int i = 0; i < 10; i++) {
            led.high();      // 亮
            Thread.sleep(500); // 500ms
            led.low();       // 灭
            Thread.sleep(500);
            System.out.println("第" + (i+1) + "次闪烁");
        }
        // 关闭LED和GPIO
        led.low();
        gpio.shutdown();
    }
}

Maven依赖(pom.xml)

<dependencies>
    <dependency>
        <groupId>com.pi4j</groupId>
        <artifactId>pi4j-core</artifactId>
        <version>1.2</version>
    </dependency>
</dependencies>

温湿度传感器(DHT11/DHT22)

接线方式

  • VCC → 3.3V
  • DATA → GPIO 4 (BCM)
  • GND → GND

传感器读取代码

import com.pi4j.wiringpi.Gpio;
import com.pi4j.wiringpi.GpioUtil;
public class DHT11Sensor {
    private static final int DHT_PIN = 4; // GPIO 4
    public static void main(String[] args) {
        // 启用引脚
        GpioUtil.enableNonPrivilegedAccess();
        Gpio.wiringPiSetup();
        DHT11Sensor dht = new DHT11Sensor();
        // 每2秒读取一次数据
        while (true) {
            double[] data = dht.readData();
            if (data != null) {
                System.out.printf("温度: %.1f°C, 湿度: %.1f%%%n", 
                    data[0], data[1]);
            }
            Thread.sleep(2000);
        }
    }
    private double[] readData() {
        // 设置引脚为输出模式发送启动信号
        Gpio.pinMode(DHT_PIN, Gpio.OUTPUT);
        Gpio.digitalWrite(DHT_PIN, Gpio.LOW);
        delay(18);
        Gpio.digitalWrite(DHT_PIN, Gpio.HIGH);
        delayMicroseconds(40);
        // 切换为输入模式
        Gpio.pinMode(DHT_PIN, Gpio.INPUT);
        // 读取40位数据
        int[] data = new int[40];
        // ... (具体时序读取代码)
        // 解析温度和湿度
        int humidity = (data[0] << 8) | data[1];
        int temperature = (data[2] << 8) | data[3];
        // 转换为实际值
        return new double[]{temperature / 10.0, humidity / 10.0};
    }
}

摄像头拍照 + 人脸检测

项目结构

raspberry-pi-camera/
├── pom.xml
├── src/main/java/
│   ├── CameraService.java
│   ├── FaceDetector.java
│   └── MainApplication.java
└── src/main/resources/
    └── haarcascade_frontalface.xml

摄像头控制服务

import java.io.BufferedReader;
import java.io.InputStreamReader;
public class CameraService {
    // 拍照命令封装
    public String takePhoto(String filename) throws Exception {
        String command = String.format(
            "raspistill -o /home/pi/photos/%s.jpg -w 640 -h 480",
            filename
        );
        return executeCommand(command);
    }
    // 视频录制
    public String startRecording(String filename, int duration) throws Exception {
        String command = String.format(
            "raspivid -o /home/pi/videos/%s.h264 -t %d -w 640 -h 480",
            filename, duration * 1000
        );
        return executeCommand(command);
    }
    private String executeCommand(String command) throws Exception {
        ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", command);
        Process process = pb.start();
        BufferedReader reader = new BufferedReader(
            new InputStreamReader(process.getInputStream()));
        StringBuilder output = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            output.append(line).append("\n");
        }
        process.waitFor();
        return output.toString();
    }
}

人脸检测

import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.objdetect.CascadeClassifier;
public class FaceDetector {
    private static final String CASCADE_PATH = 
        "/home/pi/opencv/data/haarcascades/haarcascade_frontalface_default.xml";
    public void detectFaces(String imagePath) {
        // 加载OpenCV库
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        // 读取图片
        Mat image = Imgcodecs.imread(imagePath);
        // 加载人脸检测器
        CascadeClassifier faceDetector = new CascadeClassifier(CASCADE_PATH);
        // 检测人脸
        MatOfRect faceDetections = new MatOfRect();
        faceDetector.detectMultiScale(image, faceDetections);
        System.out.println("检测到 " + faceDetections.toArray().length + " 张人脸");
        // 绘制框框
        Mat imageWithFaces = image.clone();
        for (Rect rect : faceDetections.toArray()) {
            Imgproc.rectangle(imageWithFaces, 
                new Point(rect.x, rect.y), 
                new Point(rect.x + rect.width, rect.y + rect.height),
                new Scalar(0, 255, 0), 3);
        }
        // 保存结果
        Imgcodecs.imwrite("detected_faces.jpg", imageWithFaces);
    }
}

Web服务器 + 远程控制

Spring Boot 应用程序

@SpringBootApplication
@RestController
public class RaspberryPiWebServer {
    @Autowired
    private GpioService gpioService;
    public static void main(String[] args) {
        SpringApplication.run(RaspberryPiWebServer.class, args);
    }
    @GetMapping("/")
    public String home() {
        return "树莓派设备状态:" + getSystemInfo();
    }
    @GetMapping("/gpio/{pin}/on")
    public String turnOn(@PathVariable int pin) {
        gpioService.turnOn(pin);
        return "Pin " + pin + " 已开启";
    }
    @GetMapping("/gpio/{pin}/off")
    public String turnOff(@PathVariable int pin) {
        gpioService.turnOff(pin);
        return "Pin " + pin + " 已关闭";
    }
    @GetMapping("/sensor/temperature")
    public Map<String, Double> getTemperature() {
        Map<String, Double> data = new HashMap<>();
        data.put("temperature", sensorService.readTemperature());
        data.put("humidity", sensorService.readHumidity());
        return data;
    }
}

自动化监控系统

系统架构图

graph LR
    A[传感器数据] --> B[数据采集服务]
    B --> C[消息队列]
    C --> D[数据分析]
    D --> E[告警系统]
    E --> F[Web界面]

数据采集主程序

public class MonitorSystem {
    private static final String INFLUXDB_URL = "http://localhost:8086";
    private static final String DATABASE = "raspberry_monitor";
    public static void main(String[] args) {
        // 初始化数据源
        DataSourceManager dsm = new DataSourceManager();
        dsm.addSensor(new DHT11Sensor(4));       // 温湿度
        dsm.addSensor(new GPSSensor("/dev/ttyAMA0")); // GPS
        dsm.addSensor(new MotionSensor(17));     // 运动传感器
        // 启动数据采集
        ScheduledExecutorService scheduler = 
            Executors.newScheduledThreadPool(4);
        scheduler.scheduleAtFixedRate(() -> {
            SensorData data = dsm.collectAllData();
            saveToDatabase(data);
            checkAndAlert(data);
        }, 0, 5, TimeUnit.SECONDS);
        // 实时显示
        new DashboardGUI().start();
    }
    private static void saveToDatabase(SensorData data) {
        InfluxDB influxDB = InfluxDBFactory.connect(INFLUXDB_URL);
        Point point = Point.measurement("environment")
            .time(System.currentTimeMillis(), TimeUnit.MILLISECONDS)
            .addField("temperature", data.getTemperature())
            .addField("humidity", data.getHumidity())
            .build();
        influxDB.write(DATABASE, "autogen", point);
    }
    private static void checkAndAlert(SensorData data) {
        if (data.getTemperature() > 40) {
            sendAlert("高温警告!温度达到: " + data.getTemperature());
        }
        if (data.getMotionDetected()) {
            sendAlert("检测到运动!");
            takePicture();
        }
    }
}

部署与运行

编译和打包

# 编译项目
mvn clean package
# 运行普通应用
sudo java -jar raspberry-app.jar
# 使用systemd服务管理

systemd服务配置

# /etc/systemd/system/raspberry-app.service
[Unit]
Description=Raspberry Pi Java Application
After=network.target
[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi
ExecStart=/usr/bin/java -jar /home/pi/raspberry-app.jar
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target

性能优化建议

JVM参数优化

java -Xmx512M -Xms256M 
     -XX:+UseG1GC 
     -XX:+UseCompressedOops 
     -Djava.awt.headless=true 
     -jar app.jar

资源管理

  • 使用try-with-resources管理GPIO资源
  • Implement AutoCloseable接口
  • 使用连接池管理数据库连接
try (GpioController gpio = GpioFactory.getInstance()) {
    // 使用GPIO...
} catch (IOException e) {
    // 处理异常
}
// 自动关闭和释放资源

故障排查

常见问题解决方案

public class Troubleshooting {
    // GPIO权限问题
    public void checkPermissions() {
        System.out.println("检查GPIO权限...");
        // 需要root权限或加入gpio组
        // sudo usermod -a -G gpio pi
    }
    // 网络连接检查
    public void checkNetwork() {
        // 测试服务器连接
        try {
            Socket socket = new Socket();
            socket.connect(new InetSocketAddress("server.com", 8080), 5000);
            System.out.println("网络连接正常");
        } catch (IOException e) {
            System.err.println("网络连接失败: " + e.getMessage());
        }
    }
    // 日志记录
    public static void logError(Exception e) {
        Logger logger = Logger.getLogger("RaspberryPi");
        logger.log(Level.SEVERE, "系统异常", e);
    }
}

这些案例涵盖了树莓派Java开发的主要场景,建议从LED控制开始,逐步增加复杂度,注意安全操作GPIO引脚(3.3V),并在实际部署时做好错误处理和异常监测。

抱歉,评论功能暂时关闭!