2017-08-11 141 views
0

因此,我正在编写一个应用程序,用于读取串口读取数据。这些数据来自与力传感器相连的arduino--实质上,应用程序旨在衡量某物的重量。我在这里找到串口代码:https://www.allaboutcircuits.com/projects/communicate-with-your-arduino-through-android/,我在多种不同的活动中使用它(因为我需要校准活动,实际测量活动等)。我的问题是,同一个确切的串行端口代码在一个活动中工作,并且不在另一个活动中工作。它工作在这个活动中,例如:相同的代码在不同的Android活动中运行方式不同

public class EnterDataActivity extends AppCompatActivity { 
private static final long TIMER_DELAY = 5000; 
private static final long TIMER_LENGTH = 15000; 
EditText enterMax, enterMin; 
Button submitMax, submitMin, continueButton; 
Chronometer emptyBagTimer; 
boolean firstMeasure, getEmptyBagData, canEnterMax, canEnterMin; 
ArrayList<String> emptyBagData; 
float maxLoad, minLoad; 

// serial port variables: 
public final String ACTION_USB_PERMISSION = "com.example.jake.USB_PERMISSION"; 
UsbManager usbManager; 
UsbDevice device; 
UsbSerialDevice serialPort; 
UsbDeviceConnection connection; 

UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() { //Defining a Callback which triggers whenever data is read. 
    @Override 
    public void onReceivedData(byte[] arg0) { 
     String data; 
     try { 
      data = new String(arg0, "UTF-8"); 
      if(getEmptyBagData) 
       emptyBagData.add(data); 
     } catch (UnsupportedEncodingException e) {} 
    } 
}; 
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { //Broadcast Receiver to automatically start and stop the Serial connection. 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     if (intent.getAction().equals(ACTION_USB_PERMISSION)) { 
      boolean granted = intent.getExtras().getBoolean(UsbManager.EXTRA_PERMISSION_GRANTED); 
      if (granted) { 
       connection = usbManager.openDevice(device); 
       serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection); 
       if (serialPort != null) { 
        if (serialPort.open()) { //Set Serial Connection Parameters. 
         serialPort.setBaudRate(9600); 
         serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8); 
         serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1); 
         serialPort.setParity(UsbSerialInterface.PARITY_NONE); 
         serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF); 
         serialPort.read(mCallback); 
        } else { 
         Log.d("SERIAL", "PORT NOT OPEN"); 
        } 
       } else { 
        Log.d("SERIAL", "PORT IS NULL"); 
       } 
      } else { 
       Log.d("SERIAL", "PERM NOT GRANTED"); 
      } 
     } else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) { 
      start(); 
     } else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) { 
      stop(); 
     } 
    } 
}; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_enter_data); 
    usbManager = (UsbManager) getSystemService(USB_SERVICE); 
    IntentFilter filter = new IntentFilter(); 
    filter.addAction(ACTION_USB_PERMISSION); 
    filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); 
    filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); 
    registerReceiver(broadcastReceiver, filter); 

    enterMax = (EditText) findViewById(R.id.enterMax); 
    enterMin = (EditText) findViewById(R.id.enterMin); 
    submitMax = (Button) findViewById(R.id.submitMax); 
    submitMin = (Button) findViewById(R.id.submitMin); 
    continueButton = (Button) findViewById(R.id.continueButton); 
    emptyBagTimer = (Chronometer) findViewById(R.id.emptyBagTimer); 

    firstMeasure = true; 
    getEmptyBagData = false; 
    canEnterMax = true; 
    canEnterMin = true; 

    emptyBagData = new ArrayList<>(); 

    start(); 
} 

// method: measureEmptyBag 
// description: this method is called when the button to measure the mass of the empty bag is 
// pressed. It starts the chronometer and serial port, first waiting TIMER_DELAY milliseconds 
// from the button press, then sets a boolean to true that causes the serial data to be added to 
// an arraylist over the next TIMER_LENGTH milliseconds. It then sets the next views in the 
// enter data process to visible. The firstMeasure boolean is to prevent spamming. 
public void measureEmptyBag(View view){ 
    if(firstMeasure) { 
     firstMeasure = false; 
     start(); 
     emptyBagTimer.setBase(SystemClock.elapsedRealtime()); 
     emptyBagTimer.start(); 
     emptyBagTimer.setFormat("Waiting - %s"); 
     emptyBagTimer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() { 
      @Override 
      public void onChronometerTick(Chronometer chronometer) { 
       if (SystemClock.elapsedRealtime() - emptyBagTimer.getBase() <= TIMER_DELAY) 
        emptyBagTimer.setFormat("Waiting - %s"); 
       else if (SystemClock.elapsedRealtime() - emptyBagTimer.getBase() <= TIMER_DELAY + TIMER_LENGTH) { 
        emptyBagTimer.setFormat("Calculating - %s"); 
        getEmptyBagData = true; 
       } 
       else if (SystemClock.elapsedRealtime() - emptyBagTimer.getBase() > TIMER_DELAY + TIMER_LENGTH) { 
        getEmptyBagData = false; 
        emptyBagTimer.stop(); 
        enterMax.setVisibility(View.VISIBLE); 
        submitMax.setVisibility(View.VISIBLE); 
       } 
       else 
        emptyBagTimer.setFormat("Waiting - %s"); 
      } 
     }); 
    } 
} 

// method: setMaxLoad 
// description: called when the submit button is pressed for the max load, this method trys to 
// pull the max load value from it edit text and store it. If that is successful (the user has 
// entered in a number) then it sets the next views in the enter data process to visible. 
public void setMaxLoad(View view){ 
    if(canEnterMax){ 
     try { 
      canEnterMax = false; 
      maxLoad = Float.parseFloat(enterMax.getText().toString()); 
      enterMin.setVisibility(View.VISIBLE); 
      submitMin.setVisibility(View.VISIBLE); 
     } catch (Exception e) {} // in case the user enters a non number 
    } 
} 

// method: setMinLoad 
// description: called when the submit button is pressed for the min load, this method trys to 
// pull the min load value from its edit text and store it. If that is successful (the user has 
// entered in a number) then it sets the next view in the enter data process to visible. 
public void setMinLoad(View view){ 
    if(canEnterMin){ 
     try { 
      canEnterMin = false; 
      minLoad = Float.parseFloat(enterMin.getText().toString()); 
      continueButton.setVisibility(View.VISIBLE); 
     } catch (Exception e) {} // in case the user enters a non number 
    } 
} 

// method: continuePressed 
// description: this method is called when the continue button is pressed. It averages all of the 
// data read in over the measure empty mass period to find the mass when empty, then writes that 
// value along with maxLoad and minLoad to a file for later use. Finally it starts the pump 
// activity 
public void continuePressed(View view){ 
    int emptyMassSum = 0; 
    int emptyMass; 

    // cleaning up emptyBagData to only include 3,2, or 1 digit numbers (the serial output gets 
    // wonky sometimes and spits out weird numbers that would throw off the calculations below, 
    // so those numbers need to be removed) 
    for (int i = emptyBagData.size() - 1; i >= 0; i--) 
     if (emptyBagData.get(i).length() != 3) 
      emptyBagData.remove(i); 

    // add up all the values in emptyBagData (try catch in case a non-number was read in) 
    for (int i = emptyBagData.size() - 1; i >= 0; i--) { 
     try { 
      emptyMassSum += Integer.parseInt(emptyBagData.get(i)); 
     } catch (Exception e) { 
      emptyBagData.remove(i); 
     } 
    } 

    emptyMass = emptyMassSum/emptyBagData.size(); 

    FileOutputStream outputStream; 

    String dataOut = "E" + emptyMass + "Mx" + maxLoad + "Mn" + minLoad + ";"; 

    try { 
     outputStream = openFileOutput("BagData.txt", Context.MODE_PRIVATE); 
     outputStream.write(dataOut.getBytes()); 
     outputStream.close(); 
    } catch (Exception e) { 
     continueButton.setText(R.string.file_write_error_message); 
    } 

    Intent intent = new Intent(this, PumpActivity.class); 
    startActivity(intent); 
} 

// serial port methods: 
public void start() { 
    HashMap<String, UsbDevice> usbDevices = usbManager.getDeviceList(); 
    if (!usbDevices.isEmpty()) { 
     boolean keep = true; 
     for (Map.Entry<String, UsbDevice> entry : usbDevices.entrySet()) { 
      device = entry.getValue(); 
      int deviceVID = device.getVendorId(); 
      if (deviceVID == 10755 || deviceVID == 9025)//Arduino Vendor ID 
      { 
       PendingIntent pi = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0); 
       usbManager.requestPermission(device, pi); 
       keep = false; 
      } else { 
       connection = null; 
       device = null; 
      } 

      if (!keep) 
       break; 
     } 
    } 
} 

public void stop() { 
    if(serialPort!=null) 
     serialPort.close(); 
} 
} 

通过“它的工作原理”,我的意思是我可以从串行端口进来的数据,并使用它。然而,同样的代码不能在这里工作:

public class PumpActivity extends AppCompatActivity { 
File calibrationData, bagData; 
int mass1, mass2, read1, read2, emptyMassNum; 
float maxLoad, minLoad; 
double slope, currentMassVal, emptyMass; 
boolean status, runTimer; 
TextView statusTextView, currentMassTextView; 
Button stop; 
Thread updateMass; 
ArrayList<String> inData; 

// this does two things when the handleMessage method is called: 
// 1) it takes the most recent data read in and calculates the current mass from it, then updates 
// the current mass text view to reflect that 
// 2) it takes that newly calculated mass and sees if status should change, depending on how much 
// mass there currently is. It also writes a value to the serial port (back to the arduino) 
// depending on that status. It then updates the status text view to reflect this 
Handler updateMassHandler = new Handler(){ 
    public void handleMessage(Message msg){ 
     // mass calculation 
     try{currentMassVal = calculateMass(Integer.parseInt(inData.get(inData.size()-1)));} catch (Exception e){} // try-catch in case data isn't an int 
     inData.clear(); 
     currentMassTextView.setText(String.format(getResources().getString(R.string.current_mass_string), currentMassVal)); 

     // status check with new mass 
     if (currentMassVal >= maxLoad) 
      status = true; 
     else if (currentMassVal <= minLoad) 
      status = false; 
     statusTextView.setText(String.format(getResources().getString(R.string.pump_status), getStatus())); 

     // writing back to arduino 
     if (serialPort != null) { 
      if (status) 
       serialPort.write("1".getBytes()); 
      else 
       serialPort.write("0".getBytes()); 
     } 
    } 
}; 

// serial port variables: 
public final String ACTION_USB_PERMISSION = "com.example.jake.USB_PERMISSION"; 
UsbManager usbManager; 
UsbDevice device; 
UsbSerialDevice serialPort; 
UsbDeviceConnection connection; 

UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() { //Defining a Callback which triggers whenever data is read. 
    @Override 
    public void onReceivedData(byte[] arg0) { 
     String data; 
     try { 
      data = new String(arg0, "UTF-8"); 
      inData.add(data); 
     } catch (UnsupportedEncodingException e) {} 
    } 
}; 
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { //Broadcast Receiver to automatically start and stop the Serial connection. 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     if (intent.getAction().equals(ACTION_USB_PERMISSION)) { 
      boolean granted = intent.getExtras().getBoolean(UsbManager.EXTRA_PERMISSION_GRANTED); 
      if (granted) { 
       connection = usbManager.openDevice(device); 
       serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection); 
       if (serialPort != null) { 
        if (serialPort.open()) { //Set Serial Connection Parameters. 
         serialPort.setBaudRate(9600); 
         serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8); 
         serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1); 
         serialPort.setParity(UsbSerialInterface.PARITY_NONE); 
         serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF); 
         serialPort.read(mCallback); 
        } else { 
         Log.d("SERIAL", "PORT NOT OPEN"); 
        } 
       } else { 
        Log.d("SERIAL", "PORT IS NULL"); 
       } 
      } else { 
       Log.d("SERIAL", "PERM NOT GRANTED"); 
      } 
     } else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) { 
      start(); 
     } else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) { 
      stop(); 
     } 
    } 
}; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_pump); 
    usbManager = (UsbManager) getSystemService(USB_SERVICE); 
    IntentFilter filter = new IntentFilter(); 
    filter.addAction(ACTION_USB_PERMISSION); 
    filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); 
    filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); 
    registerReceiver(broadcastReceiver, filter); 

    status = false; 
    statusTextView = (TextView) findViewById(R.id.statusTextView); 
    statusTextView.setText(String.format(getResources().getString(R.string.pump_status), getStatus())); 
    currentMassTextView = (TextView) findViewById(R.id.currentMassTextView); 
    currentMassTextView.setText(R.string.calculating_text); 
    stop = (Button) findViewById(R.id.stopButton); 
    runTimer = true; 
    currentMassVal = 0; 
    inData = new ArrayList<>(); 

    // thread that "calls" the handleMessage method in the upDateMassHandler every 100 milliseconds 
    updateMass = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      while(runTimer){ 
       updateMassHandler.sendEmptyMessage(0); 
       try{Thread.sleep(100);} catch (InterruptedException e){} 
      } 
     } 
    }); 

    // thanks to stackOverflow for the file reading code 
    // reading and parsing from calibration data 
    calibrationData = new File(getFilesDir(), "CalibrationData.txt"); 

    StringBuilder text = new StringBuilder(); 

    // reading in the calibration data from the file (of the same name) 
    try { 
     BufferedReader br = new BufferedReader(new FileReader(calibrationData)); 
     String line; 

     while ((line = br.readLine()) != null) { 
      text.append(line); 
      text.append('\n'); 
     } 
     br.close(); 
    } catch (IOException e) {} 

    // parsing values from calibration data 
    String calibData = text.toString(); 
    calibData = calibData.substring(3); 
    mass1 = Integer.parseInt(calibData.substring(0, calibData.indexOf('R'))); 
    calibData = calibData.substring(calibData.indexOf(':') + 1); 
    read1 = Integer.parseInt(calibData.substring(0, calibData.indexOf('M'))); 
    calibData = calibData.substring(calibData.indexOf(':') + 1); 
    mass2 = Integer.parseInt(calibData.substring(0, calibData.indexOf('R'))); 
    calibData = calibData.substring(calibData.indexOf(':') + 1); 
    read2 = Integer.parseInt(calibData.substring(0, calibData.indexOf('.'))); 

    slope = ((double) (mass2 - mass1)/(read2 - read1)); // calculating slope of masses and reads to allow 
                  // calculation of mass of an unknown read 

    // reading and parsing from bag data 
    bagData = new File(getFilesDir(), "BagData.txt"); 

    StringBuilder text2 = new StringBuilder(); 

    // reading in the bag data from the file (of the same name) 
    try { 
     BufferedReader br = new BufferedReader(new FileReader(bagData)); 
     String line; 

     while ((line = br.readLine()) != null) { 
      text2.append(line); 
      text2.append('\n'); 
     } 
     br.close(); 
    } catch (IOException e) {} 

    // parsing values frm bag data 
    String bagData = text2.toString(); 
    bagData = bagData.substring(1); 
    emptyMassNum = Integer.parseInt(bagData.substring(0, bagData.indexOf('M'))); 
    bagData = bagData.substring(bagData.indexOf('x') + 1); 
    maxLoad = Float.parseFloat(bagData.substring(0, bagData.indexOf('M'))); 
    bagData = bagData.substring(bagData.indexOf('n') + 1); 
    minLoad = Float.parseFloat(bagData.substring(0, bagData.indexOf(';'))); 

    emptyMass = calculateMass(emptyMassNum); // emptyMassNum is the values read in from the arduino 
              // this converts it to a mass 

    updateMass.start(); 
    start(); 
} 

// method: calculateMass 
// description: calculates the mass of the object on the transducer based off of the value read 
//    in and the data gotten from calibration 
// input: int readVal - the value read in 
// output: double - the calculated mass 
public double calculateMass(int readVal){ 
    return (slope * (readVal-read1)) + mass1; 
} 

// method: getStatus 
// description: returns a string representation of the status 
public String getStatus(){ 
    if(status) 
     return "running"; 
    else 
     return "stopped"; 
} 

// method: stop 
// description: stops everything when the stop button is pressed 
public void stop(View view){ 
    status = false; 
    runTimer = false; 
    stop(); 
    stop.setText(R.string.button_stopped); 
} 

// serial port methods: 
public void start() { 
    HashMap<String, UsbDevice> usbDevices = usbManager.getDeviceList(); 
    if (!usbDevices.isEmpty()) { 
     boolean keep = true; 
     for (Map.Entry<String, UsbDevice> entry : usbDevices.entrySet()) { 
      device = entry.getValue(); 
      int deviceVID = device.getVendorId(); 
      if (deviceVID == 10755 || deviceVID == 9025)//Arduino Vendor ID 
      { 
       PendingIntent pi = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0); 
       usbManager.requestPermission(device, pi); 
       keep = false; 
      } else { 
       connection = null; 
       device = null; 
      } 

      if (!keep) 
       break; 
     } 
    } 
} 

public void stop() { 
    if(serialPort!=null) 
     serialPort.close(); 
} 
} 

出于某种原因,在mCallback变量onReceivedData方法似乎并没有在第二个活动(一不工作)被调用。我很确定这是问题,我只是不确定为什么它被称为一个活动,而不是另一个具有相同的代码。如果该方法未被调用,那么我无法访问进入的数据,这是我的问题。

任何和所有的帮助将不胜感激!

+1

老兄这是一个问题,太多的代码。 –

回答

0

你在哪里dataSend()方法?

像这样:

private void dataSend(final String valor) { 
    final String valorM = valor;  

    runOnUiThread(new Runnable() { 
     @Override 
     public void run() {  
      try {  
       if(valorM.contains("X") && estado && (login_option.contains("Y") 
        || login_option.contains("M"))) { 

        Intent intent = new Intent(ConnectorActivity.this, OpenDoorActivity.class); 
        intent.putExtra("login_option",login_option); 
        intent.putExtra("id_user",id_user); 
        intent.putExtra("password",password); 
        intent.putExtra("connector",connector); 
        intent.putExtra("id_box",valorM); 
        intent.putExtra("timestamp_session_start", timestamp_session_start); 

        startActivity(intent); 
相关问题