• Content Count

  • Joined

  • Last visited

Everything posted by AzeoTech

  1. AzeoTech

    Moving decimal places FormatString

    Great, glad that worked. Now, sorry to be picky, but since this is forum that many people read, I'm going to mention a thing that I see a lot of, in hopes that some will change their ways: When specifying decimal numbers that are less than 1 but greater than -1, you should always precede the decimal place by a zero. So instead of: ch1*20-.1) You should put: ch1*20-0.1) The reason for this is that the decimal place can easily be missed. If you look through most scientific papers you will always see the preceding 0, so this applies to print as well as computer.
  2. AzeoTech

    Moving decimal places FormatString

    I don't get what you mean. You want to take 450 and display it as 0.00450? If so, then you need to divide by 100000. Now on the serial side. With this as input: !!\013\010 01103850.00\013\010 &&\013\010 I'd probably do this code (assuming DF 5.70+): private string datain private data private record private item while (1) try datain = device.mydevice.readuntil(10) if (strtodouble(datain) != NaN()) // if !! or &&, strtodouble() will return NaN record = strtodouble(left(datain,2)) item = strtodouble(mid(datain,2,2)) data = strtodouble(mid(datain,4,10)) // do something here with the numbers... endif catch() delay(0.1) endcatch endwhile
  3. AzeoTech

    Moving decimal places FormatString

    Well, format("%04.1f",400) will output 400.0. The easiest way to see this is to use the command / alert window and type: ? format("%04.1f",400) This is a great way to test this (and any other) function. To get 2 decimals, you need .2f, not .1f. If the Tx is saying 4.00 then that's what's going out the serial port. As for the serial in, are the carriage return / line feeds in your input? This is important. When specifying the string coming across the port, you have to include carriage returns and line feeds if they are there.
  4. AzeoTech

    Moving decimal places FormatString

    DAQFactory's function for formatting numbers is called Format(). It uses the same specifiers as the C printf() function which is very well documented on the web and elsewhere. The specifiers are also described in the help with some examples. Post if you have detailed examples of what you want. As for serial, you most definitely can do this, though not in Express as Express only works with LabJacks. In the other versions of DAQFactory you can do this. How you do it depends on the protocol. What exactly is your device outputting?
  5. Machine runtime can be a little tricky because its only really accurate if DAQFactory is running whenever the machine is running. There are two methods you can do this within DAQFactory. The first is to look at when the digital input changes state (to off) and add the difference from when it turned on. This doesn't work nearly as well as the second method, which is to accumulate with each read when the digital is on. First, you'll need a variable to store the total. Create a global variable in an autostart sequence and init it to 0: [code]global timeon = 0 Then, in the event for the digital input channel (which I'll assume you called "power") put: if (power[0] == 1) timeon += power.time[0] - power.time[1] endif That is actually all you need to calculate the machine time. Of course this will reset to 0 when you restart DAQFactory. You could get around this by using a registry variable, but you'll need to multiply by 10 or 100 if you want better than 1 second precision. I'd probably just change the event to this: if (power[0] == 1) timeon += power.time[0] - power.time[1] registry.timeon = timeon * 10 endif and the autostart variable initialization to: global timeon = registry.timeon / 10 The reason for using two variables is that the global variable will have microsecond precision. You may not need it, but since we are adding values with every reading, you can accumulate large errors if your tally is not precise. Registry variables aren't exactly the fastest to write, so I wouldn't set the Timing on my power digital channel to anything less than 1.
  6. AzeoTech

    How do I display logged data?

    I wrote this whole post and then remembered that we actually have a knowledgebase / sample download for this here. Its even better because it has transport controls to allow you to scroll back and forth: I'll keep the rest of the post just in case: Yes, but its not really a built in feature. Here are the general steps: 1) you would have to have all your channels have a timing of 0. Technically you could change the timing dynamically using script, just remember to reset the timing loops once they are changed. Use mychannel.Timing = 0 to set the timing of mychannel to 0. Do this for all channels. Then do Channel.Restart() to reset the timing loops. See the Channel Functions and Channel List Functions sections of the Channels and Conversions chapter of help. 2) Now you can load the data into DAQFactory, again with script. This time with the low level File. functions. If you are logging as CSV, you can use the readdelim() function to do it quickly. See File. functions in the Logging chapter of help. 3) Once loaded, you can create a simple loop to stuff the data into the channels at intervals. It would just be a while loop with a delay and AddValue() functions to put the data into the channels. AddValue() is also in the Channel Functions section of the help. Now depending on how big your files are, you might instead want to read one line of data at a time in that loop as you stuff it into the channels rather than reading the entire file first. The nice part about Its tough to be more specific as the best method really depends on how your application is setup and your data is logged. If, for example, you were logging to an odbc database, you'd have to query the database instead of using File. functions. Fortunately, its not terribly difficult.
  7. AzeoTech

    Six values on single graph

    Of course. But I am unsure how you expect to put six traces on a graph with different scalings without using 6 axes or a multiplier. Perhaps you can post a drawing of what you would like the graph to look like?
  8. AzeoTech

    Six values on single graph

    Certainly, just put all the traces on the same axis. If you need to add scaling for a trace or two, just put a multiplier at the end of the Y Expression. So if your Y Expression was: MyChannel You could just do: MyChannel * 10 to make the trace bigger.
  9. AzeoTech

    d0050 error

    I would recommend upgrading to the latest version of DAQFactory Express. You can go to for the latest. With the newer releases (say 5.7+), the pins will automatically be configured when you create an A to D channel on the LabJack. In older releases you had to write a line of code to configure the pins. It was only one line of code, but the new release makes it much easier.
  10. AzeoTech

    DAQFactory E-mail TLS/SSL

    No not at present. My recommendation, unless you enjoy the challenge of writing python, is to get a free email account that doesn't require SSL. I know gmail does require it, but I believe yahoo and others don't. You could always then forward that mail through your normal SSL, or simply set the reply to address to something else.
  11. AzeoTech

    Newbie sequence question

    Well, there is an undocumented function for generating PDFs in the latest releases of DAQFactory. If you are using 5.4, you can upgrade a regular version of DAQFactory from, or Express at Its not documented because it only works with some of the screen components, and hasn't really been polished up for release. It was created on customer request and since has no effect on the rest of DAQFactory, was left in so the customer could stay on the DF release path. The customer has been using it quite a while with great success. So, you are welcome to use it as long as you understand that it is not completely polished or tested so you may have to play with your pages to get it to print right, and that the function prototype / way it works may change as we improve the function for release. We also won't be able to provide any real support for it at this point other than what I describe here: The function prototype is: page.printpdf(string pagelist, string filename, xres, yres) pagelist is a comma delimited list of pages to print. If you aren't overlaying pages, then just put a single page name in quotes. Filename is the full path to the output file. Make sure and include .pdf. xres and yres are not used, but you have to pass in a number or the function will fail. This function creates uncompressed pdf files and is known to work with the graph component, table component and text components. Any other components (such as gauges, symbols, etc) probably won't work, but we've never tried. Also, some graph elements might not work. For your particular use, you also need to construct the filename. To create a filename based on date, use the formatdatetime() function: page.printpdf("Page_1","myfile_"+formatdatetime("%y%m%d",systime()) + ".pdf",0,0) See the help on formatdatetime() (in the expressions chapter, under expression reference) for the description of the qualifiers (i.e. %y, %m, etc).
  12. AzeoTech

    Graph help

    I think this might be a case where the answer is so simple you won't believe it, especially since most other apps make this much harder. So, you have two traces. The Y Expression for one is ChannelA, and the Y Expression for the other is ChannelB. Now just create another trace, this time make the Y Expression ChannelA - ChannelB. The reason its called "Y Expression" is that you can specify a calculation directly for the trace. So if you want to plot A-B you just put A-B in. If you want to Sin(A) * Cos( / C then you just put that in. You do not need to make another variable with the result of the calculation first. The only trick is that the result must be an array and it must have time associated with it. If A, B or C are channels than it will have time, and as long as at least one of the three has history and you didn't put [0] after all three, you should get an array.
  13. AzeoTech

    Logging File Name

    The easiest way is to put something like the following line in the Event of one of your channels, preferable the channel with the fastest acquisition speed: logging.mylogging.strFileName = "c:\mydata_" + formatdatetime("%y%m%d",systime()) + ".csv" This will set the logging file name every time the channel gets a new value. However, the filename will remain the same until the day changes over because the formatdatetime() function will return the same thing. Replace "mylogging" with your logging set name.
  14. AzeoTech

    Serial Sequence Data

    I wrote a nice reply and then my laptop bluescreened. Never install memory to the full capacity of the laptop and then expect a secondary video card in a docking station to not conflict Now what to do with an extra memory chip.... Anyhow, before I delve into it, at what speed do you want it to go through these values? The U12 is somewhat limited on speed, especially if you are doing anything else with it. You may be better off upgrading to a U3. They are not expensive and are much faster (among other things). You can upgrade DAQFactory Express to 5.7+ by going to
  15. AzeoTech

    Serial Sequence Data

    Are you talking about setting LabJack outputs like this, or stuff out the serial port? I'm going to guess labjack outputs. My next question then is which LabJack, as its done differently with the U12 from the UE9/U3. I'll assume the UE9/U3. In this case you use the AddRequest / GoOne format similar to what is in the LabJack documentation. I'm going to assume you are using two DACs since you have 5 in your list. I'm also going to assume you are using DAQFactory 5.70+ and that you have the include() to pull in the labjackud.h file and a using("device.labjack") as well. I'm assuming LabJack ID of 1, and DACs properly enabled. It'd be something like this (no error handling shown): private array1 = {0,0,5,0,5,5,0} private array2 = {5,0,5,0,5,0,5} private count = 0 while (count < numrows(array1)) AddRequest(1, LJ_ioPUT_DAC, 0, array1[count]) AddRequest(1, LJ_ioPUT_DAC, 1, array2[count]) GoOne(1) delay(0.1) // wait 0.1 seconds and move on count++ endwhile It wouldn't be that much different if you were using digital's. You'd just replace all the 5's with 1's and the LJ_ioPUT_DAC with LJ_ioPUT_DIGITAL_BIT. Now to explain the rest of my assumptions: DAQFactory 5.70 has an updated LabJack driver for the U3/UE9's and some other features that allow you to write code like I did above that looks almost identical to the psuedo-code in the LabJack manual, as well as C code in the LabJack examples. You can download an update for Express by going to Part of the 5.70 improvements is the include and using functions. Include() takes a path to a C header file (.h) such as the LabJackUD.h file and makes read-only variables out of all the constants found inside. For example, this makes the variable LJ_ioPUT_DAC equal 20. You only have to do this once, so you'd usually put it in an Auto-Start sequence like this: include("c:\program files\labjack\drivers\labjackud.h") using() is used to take member functions and bring them into the global namespace. Normally, to access LabJack specific functions, you'd have to do Device.LabJack.AddRequest(..). This is because DAQFactory supports a wide variety of devices and functions and this is required to keep them from colliding. However, if you are only using the LabJack, you can usually bring those functions into the global namespace, meaning you wouldn't have to type Device.LabJack. in front of every function call. Again, this function should go in an Auto-Start sequence as it only needs to be called once and would look like this: using("device.labjack.") The AddRequest / GoOne functions need to know which LabJack you are working with and I just assumed you are using ID #1. If you went into Device Configuration, for example to setup an Ethernet connection, then this is actually the Device # you specified there and not the ID. With 5.7+, if you don't go into Device Configuration, DAQFactory assumes that unknown Device #'s in these function calls, and in channels, are actually LabJack ID's to devices connected over USB. For Ethernet you have to go through Device Configuration to assign the IP address to a particular Device #. As for the DAC enabling, different LabJack's have different default capabilities, and depending on which device you have, the DAC's may be disabled by default. Use LJ_ioPUT_DAC_ENABLE to enable the DAC. You can do it in a single line in an auto-start sequence using ePut: ePut(1, LJ_ioPUT_DAC_ENABLE,0,1) ePut(1, LJ_ioPUT_DAC_ENABLE,1,1) Those lines will enable DAC's 0 and 1. You may want to implement error handling. To do this, you'd have to add GetResult() calls after the GoOne to get the result (success / error code) for each of the two commands. Then you could do something on it. It'd be something like (assuming you declared err and junk above as a privates): err = GetResult(1, LJ_ioPUT_DAC, 0, @junk) if (err != LJE_NOERROR) // error occured! endif err = GetResult(1, LJ_ioPUT_DAC, 1, @junk) if (err != LJE_NOERROR) // error occured! endif
  16. AzeoTech

    Problem to resize graphs

    You have to hold down the control key when manipulating any screen component in DAQFactory. This is because a non-control click actually activates other features, such as button press, or in the case of a graph, the zoom box. With version 5.7+ there is an optional edit mode that reverses this, requiring Ctrl-Click for pressing a button, and regular click for moving/resizing, but this is really just designed for when you need to do a lot of edits on a lot of controls at once. The traces most likely don't show because the Y axis scaling is wrong. Do you know what your signal is? It might be negative, and the since the default Y axis scaling is 0 to 10, it is not on the graph. Try right clicking on the graph, selecting Autoscale then Autoscale Y. Note that you'll need to thaw the Y axis after autoscaling if you want to use the normal axis scaling parameters.
  17. AzeoTech

    rpm measuring

    The problem with reseting the counter each time is that there is a deadband time when the counter won't count. The LabJack guys will have to tell you how long that is, but it means that during that time, if another count occurs, it won't be counted. If you never reset the counter and instead calc differences between consecutive count readings, then this doesn't happen. The worse part is that whether it misses a count or not is a bit random (really not, but it looks that way) and can't be back calculated out. For something like wind speed, it will just make your measurements slightly low (maybe 10%). For something that needs precise counting, like counting forms printed on a printing press, this is a serious issue and only the delta / no reset method should be used. As for your double counts, if you are using a mechanical switch you almost certainly have a bounce issue and should follow LabJack's advice. This exists really on just about any mechanical switch, even simple push button switches, so, for example, all the keys on your keyboard and your mouse buttons have debounce circuitry in them. If your signal was real slow, i.e. slower than the counter read rate, then you could debounce in software because you know that you should only get a maximum of one count per reading, and so you can just take the double (or often more than double) count as a single count. In your case you probably don't know this, so you'll have to debounce in hardware.
  18. You have to add a button. The Set button that appears will only set the variable. It can't trigger the addition. So, uncheck that box so the set button goes away and check Set on Submit instead and create your own button.
  19. OK, that makes a little more sense: 1) declare two variables in an auto-start sequence: global valuetoadd = 0 global currenttotal = 0 2) create an edit box, have it edit ValueToAdd. Check "Set on Submit" 3) create a button, in the action, select "Submit", then hit Add to add a second action. The second action is a quick sequence: currenttotal += valuetoadd 4) create a variable value component. Have it display CurrentTotal That's it. If you want a button to reset CurrentTotal, just create a single QuickSequence action in the button: currenttotal = 0
  20. Yes you can rotate the graph, but its not as easy as it should be (and will be in DF 6.0). What you have to do is make the graph into an X/Y graph, putting: GetTime(X expression) in your Y expression, where X expression is whatever you put in the x expression (minus any static math). Then change the X axis format to Lin (linear) and uncheck Use Time width. The problem with this is that the Y axis, which is now time, will display in DAQFactory time, not in human readable time, so you'll get numbers around a billion. You can hide this display and then create your own static labels if you want. As for the edit boxes: I don't understand what you are asking, can you provide more detail?
  21. AzeoTech

    Newbie sequence question

    OK, sorry, I think my brain stopped working there for a bit The calculation needs to be inside the while loop! waitfor(!isempty(counter[4]),1) private speed while (1) speed = ((Counter[0]-Counter[4])*0.1659) LRed = (speed >= 99) && (speed <= 101) LGreen = (speed >= 59) && (speed <= 61) delay(0.5) endwhile Otherwise it only gets calced once at start of the sequence.
  22. AzeoTech

    Newbie sequence question

    Actually, I think your problem is that the variable "speed" is not actually calculating to what you think it is and so the if statements are always out of range. I tested this exact code using simulated data and it worked fine. What I'd do is put a print statement in there so you can debug: waitfor(!isempty(counter[4]),1) private speed = ((Counter[0]-Counter[4])*0.1659) while (1) ? speed LRed = (speed >= 99) && (speed <= 101) LGreen = (speed >= 59) && (speed <= 61) delay(0.5) endwhile or just use the integrated debugger. Anyhow, the "? speed" will print the value of speed to the command/alert window. I think you'll find that it never goes inside the right ranges and thus the reason the LEDs get turned off.
  23. AzeoTech

    Newbie sequence question

    This may happen when you first start and haven't read 5 counter readings yet. Counter[4] then is empty, and Counter[1] - empty = empty, so speed becomes empty, which is fine until you do the comparison in line 3. Make sure you don't start your sequence until 5 readings have occured, or put: waitfor(!isempty(counter[4]),1) in the top of the sequence. This will cause the sequence to wait until counter[4] is not empty. It is the same as: while(isempty(counter[4]) delay(1) endwhile
  24. AzeoTech

    Newbie sequence question

    Sorry about that typo. My keyboard has been dying over the past week and not typing characters or getting stuck in Shift or Ctrl mode. Very annoying, but almost as annoying is getting used to my new keyboard First, yes, a U3 would work better for this, though as long as your loops are long and you aren't doing anything too quick the U12 might be OK. I'm not sure why your code isn't working. LRed and LGreen should be the name of your digital out channels. To test the code, I created this sequence: global speed = 0 global lred = 0 global lgreen = 0 while (1) lred = (speed >= 99) && (speed <= 101) lgreen = (speed >= 59) && (speed <= 61) delay(0.5) endwhile and then created two LEDs on a page showing the status of lred and lgreen. Then at the command line I simply typed in different speed numbers: speed = 100 and watched the LEDs switch on and off as expected. (Note that if you start with this and then try and move lred / lgreen to channels, you're going to have to do clearglobals() to get rid of the lred/lgreen global variables as well as eliminating it from the sequence.)
  25. AzeoTech

    DaqFactory for Linux?

    Actually, we are revamping our site and will have a forum in the new site in a few weeks. Its long overdue. Yes, Linux is always in the back of our minds. The trick is that supporting a program is not just about supporting the program but supporting the OS as well. And then there is the issue of so many different builds of linux. For more reliability, control and smaller footprint with the OS whilst still remaining under windows you might consider XPe. Its designed for embedded systems. Certainly a windows Mobile version will appear before linux, and PDAs are a surprising affordable platform for what you get. I often see OEMs embedding PDAs inside of instrumentation. Its very hard to get a reasonably powerful computer with a touchscreen and USB, ethernet, bluetooth, flash, etc for a few hundred bucks like you can in a PDA.