Arduino Чтение из постоянно обновляемого файла

Мне было интересно, не могли бы вы помочь некоторым старшеклассникам, которых я учу, решить эту проблему, которую я понятия не имею, как решить. Это также помогает им увидеть, каким замечательным ресурсом может быть Stackoverflow.

Мои ученики пытаются создать метеорологическую лампу с обнаружением в реальном времени с помощью Arduino. Программа на Python считывает, какая погода у почтового индекса, используя API Yahoo, и добавляет его в файл каждые 15 минут или около того.

В то же время наша Arduino использует обработку для доступа к файлу, вводит числа в последовательный порт, и Arduino считывает последовательный порт, чтобы включить правильные индикаторы, чтобы показать «погоду» (солнечный свет включит желтые светодиоды) .

Наша обработка и Arduino работают нормально (читает из файла и показывает правильные индикаторы). Он работает даже тогда, когда запущены среды Processing и 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)

person Lindsiria    schedule 07.08.2014    source источник


Ответы (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, я думаю, что то, что вы делаете для детей, просто потрясающе. Желаем удачи в создании погодной лампы!

person John Fish    schedule 07.08.2014
comment
Благодарю вас! Это закончилось работой с несколькими корректировками. Мои ученики были безумно счастливы. Девочки проходят 8-недельный 8-часовой интенсивный курс программирования пять дней в неделю, чтобы привить девочкам любовь к информатике. Они немного нервничали, так как должны были представить свои окончательные проекты важным людям, работающим в Microsoft, Amazon и Google. Вы спасатель. - person Lindsiria; 07.08.2014
comment
Вау, круто! Рад, что смог быть полезен! - person John Fish; 08.08.2014