2017-08-11 1 views
0

Donc, j'écris une application qui lit des lectures dans les données du port série. Ces données proviennent d'un arduino qui est connecté à un capteur de force - essentiellement, l'application est destinée à mesurer le poids de quelque chose. J'ai trouvé le code du port série ici: https://www.allaboutcircuits.com/projects/communicate-with-your-arduino-through-android/, et je l'utilise dans plusieurs activités différentes (puisque j'ai besoin d'une activité pour l'étalonnage, une activité pour la mesure réelle, etc.). Mon problème est que le même code de port série fonctionne dans une activité et ne fonctionne pas dans une autre. Il travaille dans cette activité, par exemple:Le même code fonctionne différemment dans différentes activités 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(); 
} 
} 

Par « ça marche », je veux dire que je peux obtenir les données à venir à partir du port série et de l'utiliser. Cependant, le même code ne fonctionne pas ici:

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(); 
} 
} 

Pour une raison quelconque, la méthode onReceivedData dans la variable mCallback ne semble pas être appelé dans la deuxième activité (celui ne fonctionne pas). Je suis assez sûr que c'est le problème, je ne suis pas sûr pourquoi il est appelé dans une activité et pas dans une autre avec le même code. Si cette méthode n'est pas appelée, je ne peux pas accéder aux données qui arrivent, ce qui est mon problème.

Une aide précieuse serait grandement appréciée!

+1

Mec c'est trop code pour une question. –

Répondre

0

Où est la méthode dataSend()?

Comme ceci:

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);