PLX-DAQ version 2 - now with 64 bit support! (and further new features)

Hi Net Devil!

First wanted to say thank you so much for creating a PLX DAQ that I can download on my Mac (and sort of works!). In my graduate thesis I'm using multiple sensors to provide solar cell researchers with a light meter (that measures in W/m2 not in Lux) using Arduino.

I was trying to do live data acquisition to Matlab to no avail, when I came across PLX DAQ (the og version), which of course is not available to us Mac users. I then came across this posting and was so relieved to be able to download and have the excel sheet and UI actually pop up! (version 2.11)

However, on Macs the port number is not a numeral but is a string (in my case "/dev/cu.usbmodem14101", but the UI won't accept anything other than a numeral. Do you know if there's any way around this? Or where I could start looking to possibly still use the PLX DAQ you created but without this issue? It would be a lfiesaver because this is exactly what I need to complete my dissertation!

Thank you in advance, I cannot explain how awesome this is that you created your own version that's (close to) working for us Mac users excluded from the original!

Hi folks :slight_smile:

@merlins_ghost: nice work on enhancing the program to what you need or see fit. That is the spirit of the community :slight_smile: I like the wakeup idea :slight_smile: Screenupdating and calculation turnoff is tricky as most people need to see the results in real time rather then after some fixed time, but yeah that will definitely improve stability.
Regarding drop downs to present only "working" options to the user, that is exactly what I got rid of from the previous PLX DAQ as I think it is best to let the user decide what is needed and just present a valid default. E.g. baud rate, I know there are typical rates Arduino or serial communication in general makes use of, but I have not had problems using arbitrary values like 6666 or others. If those are needed for someone... well why not :slight_smile: I was recently thinking about moving the project to Git, maybe you could create a pull request / branch then and publish your code as well :slight_smile:

@annagrad1234: oh boy, nice to know the program came such a long way to be used in these levels of sophisticated academic areas :slight_smile: putting no pressure on me helping you out now, do you :wink:
There have been quite a few people asking for Mac support and I always told them to give it a try but never received any positive feedback as I think there is little to no chance to actually getting it done :-/ Excel and VBA on Mac seem to be very different...
Nevertheless if you could give it a try then it is easy to just remove the check for the port, but it might not be enough.
If you could open the VBA editor in Excel (in Windows it is via Alt+F11), in the navigation panel on the left side expand the "Forms", right click (har har on a Mac...) "frmStampDAQ" and select view code. Search for Private Sub cmdConnect_Click() and there remove the block If Not IsNumeric(cboPort.Text) Then (.... 6 lines later ....) End If
That way you might enter a string into the text field now.

However there are 3 occurrences within the code where the port is used in a technical call via CommOpen(cboPort.Text, "COM" & CStr(cboPort.Text), "baud=" & cboBAUD.Text & " parity=N data=8 stop=1", BufferSerialDeviceRead, BufferSerialDeviceWrite)
Maybe you will have to remove the "COM" part in that call in order for it to work properly.

Taking a look at the CommOpen function in modCOMM module (also within the VBA code) it calls udtPorts(IntportID).lngHandle = CreateFile("\\.\COM" & IntportID, GENERIC_READ Or _ GENERIC_WRITE, 0, ByVal 0&, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
Thus once more a COM reference that you might have to workaround on Mac :-/ Might be necessary to take a look at the CreateFile handle to see what it is expecting there on a Mac.

I hope you find the time and urge to invest a few minutes into this as I would love to be able to present PLX DAQ v2 to the Mac community as well. I myself do not have one at hand unfortunately :frowning:

Cheers and kind regards

Jonathan

Hi @NetDevil ,
I was using PLX- v2.11. Also, I I wanted to implement excel file clearing and again data collection every time my load cell is tared. But it happens that the data is appending . How can I implement the code so that when code is tared, data will start from row 2? Really appreciate any kind of help.
My arduino code is

/*
   -------------------------------------------------------------------------------------
   HX711_ADC
   Arduino library for HX711 24-Bit Analog-to-Digital Converter for Weight Scales
   Olav Kallhovd sept2017
   -------------------------------------------------------------------------------------
*/

/*
   Settling time (number of samples) and data filtering can be adjusted in the config.h file
   For calibration and storing the calibration value in eeprom, see example file "Calibration.ino"

   The update() function checks for new data and starts the next conversion. In order to acheive maximum effective
   sample rate, update() should be called at least as often as the HX711 sample rate; >10Hz@10SPS, >80Hz@80SPS.
   If you have other time consuming code running (i.e. a graphical LCD), consider calling update() from an interrupt routine,
   see example file "Read_1x_load_cell_interrupt_driven.ino".

   This is an example sketch on how to use this library
*/

#include <HX711_ADC.h>
#if defined(ESP8266)|| defined(ESP32) || defined(AVR)
#include <EEPROM.h>
#endif
int row_excel = 0; // number of lines

//pins:
const int HX711_dout = 3; //mcu > HX711 dout pin
const int HX711_sck = 2; //mcu > HX711 sck pin

//HX711 constructor:
HX711_ADC LoadCell(HX711_dout, HX711_sck);
float calibrationValue;
const int calVal_eepromAdress = 0;
unsigned long t = 0;

void setup() {
  //float calibrationValue;
  Serial.begin(9600); delay(10);
  Serial.println();
  Serial.println("Starting...");

  LoadCell.begin();
  Serial.println("Press T to tare");
// LoadCell.set_LoadCell(calibrationValue);
 LoadCell.tare();
  
  float calibrationValue; // calibration value (see example file "Calibration.ino")
  calibrationValue =7389.5; //7387.910156;//7386.902787 in normal room light; // uncomment this if you want to set the calibration value in the sketch
#if defined(ESP8266)|| defined(ESP32)
  //EEPROM.begin(512); // uncomment this if you use ESP8266/ESP32 and want to fetch the calibration value from eeprom
#endif
  //EEPROM.get(calVal_eepromAdress, calibrationValue); // uncomment this if you want to fetch the calibration value from eeprom

  unsigned long stabilizingtime = 2000; //2000// preciscion right after power-up can be improved by adding a few seconds of stabilizing time
  boolean _tare = true; //set this to false if you don't want tare to be performed in the next step
  LoadCell.start(stabilizingtime, _tare);
  if (LoadCell.getTareTimeoutFlag()) {
    Serial.println("Timeout, check MCU>HX711 wiring and pin designations");
    while (1);
   Serial.println("CLEARDATA"); // clear excel sheet
  Serial.println("LABEL,Time,Timer,calibration factor, weight in grams,Num of Rows"); // column headers
  
  }
  else {
    LoadCell.setCalFactor(calibrationValue); // set calibration value (float)
    Serial.println("Startup is complete");
  }
}

void loop() {
  
  static boolean newDataReady = 0;
  const int serialPrintInterval = 0; //increase value to slow down serial print activity

  // check for new data/start next conversion:
  if (LoadCell.update()) newDataReady = true;

  // get smoothed value from the dataset:
  if (newDataReady) {
    if (millis() > t + serialPrintInterval) {
      float i = LoadCell.getData();
     // Serial.print("          Load_cell output val:");
      row_excel++; // row number + 1
   Serial.print("DATA,TIME,"); // excel record current date and time
   Serial.print(millis()); // excel record timer
   Serial.print(",");
 Serial.print(calibrationValue);  
   Serial.print(",");
  //Serial.print("    Weight: ,");
   Serial.print(i, 4);  //Up to 3 decimal points
   Serial.print(",");
   Serial.println(row_excel);
      newDataReady = 0;
      t = millis();
    }
  }

  // receive command from serial terminal, send 't' to initiate tare operation:
  if (Serial.available() > 0) {
    char inByte = Serial.read();
    if (inByte == 't'|| inByte == 'T') LoadCell.tareNoDelay();
  }

  // check if last tare operation is complete:
  if (LoadCell.getTareStatus() == true) {
    Serial.println("Tare complete");
  }
delay(10);
}

"CLEARDATA" empties the sheet and sets the row number to 2, I only see where you "CLEARDATA" the one time during setup. If you want to clear after each tare then you need to include the instruction in the tare routine which seems like it might be similar to the following.

  if (Serial.available() > 0) {
    char inByte = Serial.read();
    if (inByte == 't'|| inByte == 'T') LoadCell.tareNoDelay();

  Serial.println("CLEARDATA"); // clear excel sheet
  Serial.println("LABEL,Time,Timer,calibration factor, weight in grams,Num of Rows"); // column headers

  }

Hi,

Thanks. I used CLEARDATA in setup and now my data does not append upon reset.

Hi @NetDevil ,
Thanks for your nice program. This is doing most of the job I wanted to do.
But I have several problems. Hope you could help.

  1. Excel Cursh: My excel suddenly crushes when I use PLX-DAQ. Sometimes, when I start acquisition, it crushes within few minutes, sometimes it crushes when I try to disconnect Arduino. My excel is updated. This problem does not happen with any other serial monitor. Only happening here. Is it something to do with macros or my Arduino code ? Could you please help?

  2. Time lag to start data acquisition : Excel starts acquisition after 4s. This lag is huge for my application. Why this is happening and how can I reduce this time lag?

My arduino code is as below:

/*
   -------------------------------------------------------------------------------------
   /*
   -------------------------------------------------------------------------------------
   HX711_ADC
   Arduino library for HX711 24-Bit Analog-to-Digital Converter for Weight Scales
   Olav Kallhovd sept2017
   -------------------------------------------------------------------------------------
*/

/*
   Settling time (number of samples) and data filtering can be adjusted in the config.h file
   For calibration and storing the calibration value in eeprom, see example file "Calibration.ino"

   The update() function checks for new data and starts the next conversion. In order to acheive maximum effective
   sample rate, update() should be called at least as often as the HX711 sample rate; >10Hz@10SPS, >80Hz@80SPS.
   If you have other time consuming code running (i.e. a graphical LCD), consider calling update() from an interrupt routine,
   see example file "Read_1x_load_cell_interrupt_driven.ino".

   This is an example sketch on how to use this library
*/

#include <HX711_ADC.h>
#if defined(ESP8266)|| defined(ESP32) || defined(AVR)
#include <EEPROM.h>
#endif
int row_excel = 0; // number of lines

//pins:
const int HX711_dout = 3; //mcu > HX711 dout pin
const int HX711_sck = 2; //mcu > HX711 sck pin

//HX711 constructor:
HX711_ADC LoadCell(HX711_dout, HX711_sck);
float calibrationValue;
const int calVal_eepromAdress = 0;
unsigned long t = 0;

void setup() {
  //float calibrationValue;
  Serial.begin(57600); 
  Serial.println("CLEARDATA"); 
  Serial.println("LABEL,Time,Timer,weight in grams,Num of Rows"); // column headers
  // Serial.println("SAVEWORKBOOKAS,");
   
  delay(10);
  
  Serial.println();
  Serial.println("Starting...");

  LoadCell.begin();
  Serial.println("Press T to tare");
// LoadCell.set_LoadCell(calibrationValue);
 LoadCell.tare();
  
  float calibrationValue; // calibration value (see example file "Calibration.ino")
  calibrationValue =7389.5; //7387.910156;//7386.902787 in normal room light; // uncomment this if you want to set the calibration value in the sketch
#if defined(ESP8266)|| defined(ESP32)
  //EEPROM.begin(512); // uncomment this if you use ESP8266/ESP32 and want to fetch the calibration value from eeprom
#endif
  //EEPROM.get(calVal_eepromAdress, calibrationValue); // uncomment this if you want to fetch the calibration value from eeprom

  unsigned long stabilizingtime = 200; //2000// preciscion right after power-up can be improved by adding a few seconds of stabilizing time
  boolean _tare = true; //set this to false if you don't want tare to be performed in the next step
  LoadCell.start(stabilizingtime, _tare);
  
  if (LoadCell.getTareTimeoutFlag()) {
    Serial.println("Timeout, check MCU>HX711 wiring and pin designations");
    while (1);
   Serial.println("CLEARDATA"); // clear excel sheet
  Serial.println("LABEL,Time,Timer, weight in grams,Num of Rows"); // column headers
  //Serial.println("LABEL,Time,Timer,calibration factor, weight in grams,Num of Rows"); // column headers
  
  }
  else {
    LoadCell.setCalFactor(calibrationValue); // set calibration value (float)
    Serial.println("Startup is complete");
  }
}

void loop() {
   //Serial.println( (String) "SAVEWORKBOOKAS","myName");
   
  static boolean newDataReady = 0;
  const int serialPrintInterval = 0; //increase value to slow down serial print activity

  // check for new data/start next conversion:
  if (LoadCell.update()) newDataReady = true;

  // get smoothed value from the dataset:
  if (newDataReady) {
    if (millis() > t + serialPrintInterval) {
      float i = LoadCell.getData();
     // Serial.print("          Load_cell output val:");
      row_excel++; // row number + 1
   Serial.print("DATA,TIME,"); // excel record current date and time
   Serial.print(millis()); // excel record timer
   Serial.print(",");
 //Serial.print(calibrationValue);  
  // Serial.print(",");
  //Serial.print("    Weight: ,");
   Serial.print(i, 4);  //Up to 3 decimal points
   Serial.print(",");
   Serial.println(row_excel);
      newDataReady = 0;
      t = millis();
      
    }
  }

  // receive command from serial terminal, send 't' to initiate tare operation:
  if (Serial.available() > 0) {
    char inByte = Serial.read();
    //Serial.println("SAVEWORKBOOK");
        if (inByte == 't'|| inByte == 'T') {
    LoadCell.tareNoDelay();
    }
  }

  // check if last tare operation is complete:
  if (LoadCell.getTareStatus() == true) {
    Serial.println("Tare complete");
  }
//delay(1000);
}

Hope you can help me to solve these issues.Thanks in advance. Thanks for developing PLX DAQ v 2 for the community..

Hello,

Sorry for so late response, but there were many other things so i just put thi project aside.
Any how i managed to put things together -hardware, electrical stuff etc.
SO no i start testing the system.
Seems it works pretty good.
For data - message exchange i go with writing index into excel cell and checking it after with arduino cod.

So wen conditions are meet arduioon changes enable cell value in excel from 1 to 0 and in next step ehn it check for condition enable if stops.
So some how this is resolved.
But i am facing with other problem as from time to time i get message could not connect check port settings.
For now i did not figure out what is the condition for happening. IS there any know reason or solution for this problem?

Thanks.
kind regards,
marko

Yeah, I was not too worried about seeing the data saved and did not need calculations turned on since I can still see the data coming in through the log window and can turn the calculations and screen updating back on after the last row of data is received when I get the end of data command. :slightly_smiling_face: I will look into forking as you suggest since someone else might have use of my changes. :slightly_smiling_face:

I want to save all data of column C by user defined path and user defined name. It has to be declared as soon as I connect Arduino. In my project, it restart several times and I want to save last data appeared before disconnecting arduino.

How can I achieve all these? Can anyone please help?

My current Arduino code is as below:

/*
   -------------------------------------------------------------------------------------
   /*
   -------------------------------------------------------------------------------------
   HX711_ADC
   Arduino library for HX711 24-Bit Analog-to-Digital Converter for Weight Scales
   Olav Kallhovd sept2017
   -------------------------------------------------------------------------------------
*/

/*
   Settling time (number of samples) and data filtering can be adjusted in the config.h file
   For calibration and storing the calibration value in eeprom, see example file "Calibration.ino"

   The update() function checks for new data and starts the next conversion. In order to acheive maximum effective
   sample rate, update() should be called at least as often as the HX711 sample rate; >10Hz@10SPS, >80Hz@80SPS.
   If you have other time consuming code running (i.e. a graphical LCD), consider calling update() from an interrupt routine,
   see example file "Read_1x_load_cell_interrupt_driven.ino".

   This is an example sketch on how to use this library
*/

#include <HX711_ADC.h>
#if defined(ESP8266)|| defined(ESP32) || defined(AVR)
#include <EEPROM.h>
#endif
int row_excel = 0; // number of lines

//pins:
const int HX711_dout = 3; //mcu > HX711 dout pin
const int HX711_sck = 2; //mcu > HX711 sck pin

//HX711 constructor:
HX711_ADC LoadCell(HX711_dout, HX711_sck);
float calibrationValue;
const int calVal_eepromAdress = 0;
unsigned long t = 0;

void setup() {
  //float calibrationValue;
  Serial.begin(57600); 
  Serial.println("CLEARDATA"); 
  Serial.println("LABEL,Time,Timer,weight in grams,Num of Rows"); // column headers
  // Serial.println("SAVEWORKBOOKAS,");
   
  delay(10);
  
  Serial.println();
  Serial.println("Starting...");

  LoadCell.begin();
  Serial.println("Press T to tare");
// LoadCell.set_LoadCell(calibrationValue);
 LoadCell.tare();
  
  float calibrationValue; // calibration value (see example file "Calibration.ino")
  calibrationValue =7389.5; //7387.910156;//7386.902787 in normal room light; // uncomment this if you want to set the calibration value in the sketch
#if defined(ESP8266)|| defined(ESP32)
  //EEPROM.begin(512); // uncomment this if you use ESP8266/ESP32 and want to fetch the calibration value from eeprom
#endif
  //EEPROM.get(calVal_eepromAdress, calibrationValue); // uncomment this if you want to fetch the calibration value from eeprom

  unsigned long stabilizingtime = 200; //2000// preciscion right after power-up can be improved by adding a few seconds of stabilizing time
  boolean _tare = true; //set this to false if you don't want tare to be performed in the next step
  LoadCell.start(stabilizingtime, _tare);
  
  if (LoadCell.getTareTimeoutFlag()) {
    Serial.println("Timeout, check MCU>HX711 wiring and pin designations");
    while (1);
   Serial.println("CLEARDATA"); // clear excel sheet
  Serial.println("LABEL,Time,Timer, weight in grams,Num of Rows"); // column headers
  //Serial.println("LABEL,Time,Timer,calibration factor, weight in grams,Num of Rows"); // column headers
  
  }
  else {
    LoadCell.setCalFactor(calibrationValue); // set calibration value (float)
    Serial.println("Startup is complete");
  }
}

void loop() {
   //Serial.println( (String) "SAVEWORKBOOKAS","myName");
   
  static boolean newDataReady = 0;
  const int serialPrintInterval = 0; //increase value to slow down serial print activity

  // check for new data/start next conversion:
  if (LoadCell.update()) newDataReady = true;

  // get smoothed value from the dataset:
  if (newDataReady) {
    if (millis() > t + serialPrintInterval) {
      float i = LoadCell.getData();
     // Serial.print("          Load_cell output val:");
      row_excel++; // row number + 1
   Serial.print("DATA,TIME,"); // excel record current date and time
   Serial.print(millis()); // excel record timer
   Serial.print(",");
 //Serial.print(calibrationValue);  
  // Serial.print(",");
  //Serial.print("    Weight: ,");
   Serial.print(i, 4);  //Up to 3 decimal points
   Serial.print(",");
   Serial.println(row_excel);
      newDataReady = 0;
      t = millis();
      
    }
  }

  // receive command from serial terminal, send 't' to initiate tare operation:
  if (Serial.available() > 0) {
    char inByte = Serial.read();
    //Serial.println("SAVEWORKBOOK");
        if (inByte == 't'|| inByte == 'T') {
    LoadCell.tareNoDelay();
    }
  }

  // check if last tare operation is complete:
  if (LoadCell.getTareStatus() == true) {
    Serial.println("Tare complete");
  }
//delay(1000);
}

Hi everyone,

I get started using the PLX_DAQ_v2, really useful!! I am facing an issue with placing Labels.
I set the labels in setup() but when I run the excel with the PLX, the labels do not update. However, I managed to get it to work after inserting a 3s delay after Serial.begin();

Also every time I upload the sketch I have to restart the Arduino before taking effect the new labels

void setup() {
  Serial.begin(115200);

  delay(3000);
  
  analogReadResolution(12); // set the resolution to 12bit (0-4095)
  Serial.println("CLEARDATA");
  Serial.println("LABEL,Resistance,Voltage,ADC"); 
}

This is how it supposed to work or I am doing something wrong?

Hi folks,
sorry at all for my late response - I was on vacation and could only read the notifications but not reply properly...

Big shoutout once again to @sumguy for being here to help! I would like to say you are the Robin to my Batman, but you are more then just a sidekick. Nice to know you are here!

Getting to work:


@rock_roll there are multiple problems you describe so let me tackle them one by one:

  1. Yes, Excel crashes are a know issue in PLX DAQ that comes with the way Excel handles the VBA code. When doing heavy lifting in the code you should not interact with Excel (e.g. moving the windows, selecting cells, clicking and holding buttons). All of that will just kill the flow and thus make Excel crash. As mentioned by merlins_ghost you can disable screenupdating and autocalculations but that way you won't see what is going on anymore and should re-activate the features after a certain time limit. It has shown that is also best to use the least possible baud rate. Faster is not always better if you do not need to go that fast. 9600 is good enough for nearly everyone.
  2. I can not explain the time lag, sorry. Never heard of an issue like that before. Do other serial monitors have the delay as well? E.g. the Arduino IDE build in monitor? When using PLX DAQ UI and pressing the connect button, do you have the options set to "Reset on connect"? That way PLX DAQ will tell your Arduino to restart and load all anew the first thing after connection. You should have a communication established right at the beginning of your code that way.
  3. To only save contents of column C by custom name and path upon disconnect or connect is tricky. There is a SAVEWORKBOOKAS command in PLX DAQ, go check that out in the Beginners Guide document please. It might do your trick. But you have to call that from your Arduino code and pass the desired name. If it does not fit then I am afraid you will need to write some own (but rather easy) code in VBA / Excel.

@marchello_si good to know your issues got fixed! Regarding the port problem it could be that your Arduino COM port was blocked by "some other" application. This can either be a previous PLX DAQ connection (if you did a dirty disconnect by Excel crash) and can be solved by just unplugging and re-plugging the USB cable. Or maybe Arduino IDE or Arduino Serial Monitor were open in parallel? COM ports allow only a one-at-a-time connection. Shitty but that's the way it is....


@Nikosant03 thank you very much for the feedback, it is much appreciated :slight_smile: I saw you post on Save data to specific excel cells and @sherzaad mentioning my program. Nice it is working out for you.
Now, regarding the problem you have. Have you checked the box "Reset on connect"? After uploading your new sketch Arduino directly executes it and runs through the setup function. If those commands are not captured by PLX DAQ (but rather still by the Arduino IDE) the labels will not be displayed. By checking the checkbox PLX DAQ will reset your Arduino after successfully connecting, thus being able to directly capture the LABEL commands.


Hopefully I covered all open questions. Just make sure to @ mention me in your answers thus I will definitely get a notification from the forum :slight_smile:

Cheers!

Hello,

Regards problem with message could not connect it happens when code is running.
In my case there should be code run for about 3-6 min and data transferred from arduino to excel.
while sending data arduino is monitoring the cell in excel for enable condition. as long other conditions are not meet code is running. but as mentioned it just happens that during code run it breaks connection. Nothing else in being connected to computer to interfere ports or what so ever.
Will try to find out what are actuall conditions for crash.
if find any thing will let you know.

thanks.
kind regards.
marko