【问题标题】:Arduino Reading from a constantly updating fileArduino 从不断更新的文件中读取
【发布时间】:2014-09-30 02:27:26
【问题描述】:

我想知道您是否可以通过解决这个我不知道如何解决的问题来帮助我正在教的一些高中生。这也有助于他们了解 Stackoverflow 是多么棒的资源。

我的学生正在尝试使用 arduino 创建具有实时检测功能的天气灯。一个 python 程序使用 Yahoo API 读取邮政编码的天气情况,并每隔 15 分钟左右将其附加到一个文件中。

同时,我们的Arduino正在使用Processing访问文件,将数字推入串口,arduino读取串口打开正确的灯以显示“天气”(sunny会打开黄色 LED)。

我们的处理和 Arduino 工作正常(它从文件中读取并显示正确的灯)。它甚至在处理和 Arduino 环境正在运行并且您手动将数字添加到文件时也可以工作。我们的 Python 文件也可以通过将正确的天气输出到文件中来正常工作。

问题...这两个脚本不能同时运行。如果 Python 正在执行真实世界的更新(每 15 分钟检查一次天气),则处理将不会触及文件。在 Python 脚本完全完成并且我们(再次)启动处理环境之前,不会读取该文件。如果它不会访问文件并让灯光随时间变化,这将违背现实世界更新的目的和该项目的意义。

在相关说明中,我知道将 Wifi Shield 用于 Arduino 会更好,但我们没有时间也没有资源来获得它。这是 80 美元,他们有一周的时间从头到尾完成这个项目。

这里是代码。

文件的外观

2, 3, 4, 3, 2

2 - 晴天(打开引脚 2)... 3 - 下雨(打开引脚 3)...

阿杜诺

 void setup() { 
     // initialize the digital pins as an output.
     pinMode(2, OUTPUT);
     pinMode(3, OUTPUT);
     pinMode(4, OUTPUT);
    // Turn the Serial Protocol ON
     Serial.begin(9600);
}

void loop() {
     byte byteRead;

     /* check if data has been sent from the computer: */
     if (Serial.available()) {
         /* read the most recent byte */
         byteRead = Serial.read();
         //You have to subtract '0' from the read Byte to convert from text to a number.
         byteRead=byteRead-'0';

         //Turn off all LEDs if the byte Read = 0
         if(byteRead==0){
             //Turn off all LEDS
             digitalWrite(2, LOW);
             digitalWrite(3, LOW);
             digitalWrite(4, LOW);

         }

         //Turn LED ON depending on the byte Read.
        if(byteRead>0){
             digitalWrite((byteRead), HIGH); // set the LED on
             delay(100);
         }
     }
 }

处理

import processing.serial.*;
import java.io.*;
int mySwitch=0;
int counter=0;
String [] subtext;
Serial myPort;


void setup(){
     //Create a switch that will control the frequency of text file reads.
     //When mySwitch=1, the program is setup to read the text file.
     //This is turned off when mySwitch = 0
     mySwitch=1;

     //Open the serial port for communication with the Arduino
     //Make sure the COM port is correct
     myPort = new Serial(this, "COM3", 9600);
     myPort.bufferUntil('\n');
}

void draw() {
     if (mySwitch>0){
        /*The readData function can be found later in the code.
        This is the call to read a CSV file on the computer hard-drive. */
        readData("C:/Users/Lindsey/GWC Documents/Final Projects/lights.txt");

        /*The following switch prevents continuous reading of the text file, until
        we are ready to read the file again. */
        mySwitch=0;
     }
     /*Only send new data. This IF statement will allow new data to be sent to
     the arduino. */
     if(counter<subtext.length){
        /* Write the next number to the Serial port and send it to the Arduino 
        There will be a delay of half a second before the command is
        sent to turn the LED off : myPort.write('0'); */
        myPort.write(subtext[counter]);
         delay(500);
         myPort.write('0');
         delay(100);
         //Increment the counter so that the next number is sent to the arduino.
         counter++;
     } else{
         //If the text file has run out of numbers, then read the text file again in 5 seconds.
         delay(5000);
         mySwitch=1;
     }
} 


/* The following function will read from a CSV or TXT file */
void readData(String myFileName){

     File file=new File(myFileName);
     BufferedReader br=null;

     try{
        br=new BufferedReader(new FileReader(file));
        String text=null;

        /* keep reading each line until you get to the end of the file */
        while((text=br.readLine())!=null){
            /* Spilt each line up into bits and pieces using a comma as a separator */
            subtext = splitTokens(text,",");
        }
     }catch(FileNotFoundException e){
        e.printStackTrace();

     }catch(IOException e){
        e.printStackTrace();

     }finally{
        try {
            if (br != null){
                br.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
     }
}

Python 代码

import pywapi
import time

# create a file
file = open("weatherData.txt", "w+")
file.close()

for i in range(0,10):
    weather = pywapi.get_weather_from_weather_com("90210")['current_conditions']['text']
    print(weather)

    if "rain" or "showers" in weather:
        weatherValue = "4"

    if "Sun" in weather:
        weatherValue = "2"
    if "thunder" in weather:
        weatherValue = "5"
    #elif "Cloud" in weather:
    if "Cloudy" in weather: 
        weatherValue = "3"
        print(weatherValue)

    # append the file with number
    # append with a comma after and space
    file = open("weatherData.txt","a")
    file.write(weatherValue + ", ")
    file.close()

    time.sleep(10)

【问题讨论】:

    标签: python arduino processing weather yahoo-weather-api


    【解决方案1】:

    这实际上不一定是三部分编程挑战 - 因为您可以使用 PySerial 模块。这是我过去用来检索在线数据并通过串行端口将其直接传递给 arduino 的模块。首先,您必须按照我给您的链接中的说明安装模块。在 python 程序中,您可以将代码更改为如下所示:

    import pywapi
    import time
    import serial #The PySerial module
    
    # create a file
    file = open("weatherData.txt", "w+")
    file.close()
    
    ser = serial.Serial("COM3", 9600) #Change COM3 to whichever COM port your arduino is in
    
    for i in range(0,10):
        weather = pywapi.get_weather_from_weather_com("90210")['current_conditions']['text']
        print(weather)
    
        if "rain" or "showers" in weather:
            weatherValue = "4"
    
        if "Sun" in weather:
            weatherValue = "2"
        if "thunder" in weather:
            weatherValue = "5"
        #elif "Cloud" in weather:
        if "Cloudy" in weather: 
            weatherValue = "3"
            print(weatherValue)
    
        # append the file with number
        # append with a comma after and space
        file = open("weatherData.txt","a")
        file.write(weatherValue + ", ")
        file.close()
    
        #Sending the file via serial to arduino
        byte_signal = bytes([weatherValue])
        ser.write(byte_signal)
    
        time.sleep(10)
    

    您甚至不需要将其写入文件,但如果您打算以其他方式使用该文件,程序仍应创建相同的文件。

    您的 arduino 代码可能如下所示:

    int weather_pin = 0;
    void setup() {
      Serial.begin(9600);
      pinMode(2, OUTPUT);
      pinMode(3, OUTPUT);
      pinMode(4, OUTPUT);
    }
    
    void loop() {
      if(weather_pin>0){
        digitalWrite(weather_pin, HIGH);
      }
    }
    
    void serialEvent() {
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      weather_pin = Serial.read();
    }
    

    这应该可以!我让它在我的系统上运行,但每个系统都不同,所以如果它不起作用,请随时给我留言。如果您对代码有任何疑问,同样的处理。作为一名了解 stackoverflow 之美的高中生,我认为您为孩子们所做的一切真是太棒了。祝您制作天气灯好运!

    【讨论】:

    • 谢谢!最终进行了一些调整。我的学生们高兴极了。女孩们参加了为期 8 周、每天 8 小时、每周 5 天的强化编程课程,让女孩们爱上计算机科学。他们有点压力,因为他们应该向微软、亚马逊和谷歌的重要人员展示他们的最终项目。你是救生员。
    • 哇,太棒了!很高兴我能帮上忙!
    猜你喜欢
    • 2013-05-19
    • 2021-02-14
    • 1970-01-01
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    • 1970-01-01
    • 2020-10-28
    相关资源
    最近更新 更多