ammolytics / projects Goto Github PK
View Code? Open in Web Editor NEWSource code and instructions for do-it-yourself projects.
Home Page: https://blog.ammolytics.com
License: MIT License
Source code and instructions for do-it-yourself projects.
Home Page: https://blog.ammolytics.com
License: MIT License
Perhaps just search for and connect to the trickler when the app starts?
The Open Trickler would benefit from a web-based UI (hosted at http://opentrickler.local) to allow:
The Open Trickler is available for iOS through TestFlight using the following link:
https://testflight.apple.com/join/1XSoUPL3
It takes longer to develop iOS apps because Apple requires jumping through a few hoops, such as:
Many of the questions for the OpenTrickler could be answered in an FAQ.
Common items:
Currently, the write-operation creates a 10ms delay during which time acceleration data is no longer being collected.
Ideally, data would still be collected during this time so as to prevent any loss.
Hello at all.
I´m a greenhorn with raspberry and programming and i need help.
first I set up and built everything according to the instructions.
i have connected the raspberry to the app.
after entering the weight and the start button, the trickler does not run.
if I drive the diode directly with electricity, the motor runs
i have no idea where the error is.
can someone help me?
I can also send the raspberry logs.
sorry for my bad English. I'm from Germany
Thank you for your help in advance.
I would switch to storing raw data, rather than strings.
There is probably a significant overhead in doing a string conversion, because you're implicitly calling itoa a bunch of times. You'd be better off having three 16-bit arrays to store the accelerations and just putting the raw measurements in there each loop.
projects/accelerometer/sensor_logger.ino
Lines 162 to 172 in a298bcd
It will also save a lot of space. This string "m/s^2, "
alone contains as much data as a single 3 axis measurement!
The Adafruit library also does a bunch of float calculations which is also going to be a lot of extra cycles, but worry about that when you've optimised as far as you can with their library.
So in principle your max data rate is 3 x 5000 x 16 bits or around 240kbaud. From your writeup it looks like you're capturing at a much lower rate (around 140Hz). I'd be curious to see how much faster you can write to disk just making the changes above.
Some folks have suggested adding support for an automatic powder drop, controlled by a servo. Anyone who has experience with this can chime in here with suggestions.
Since it's an optional feature, it should be treated as such in the software (controller and Mobile).
I'd appreciate a small wiring guide as in "connect pin X to Featherboard pin Y" as it's not really obvious whether it has to be wired via I2C or SPI
This project is great! And I would love to bring it in our shooting club for these people who like accurate reloads. Unfortunately I'm not able to get the RPi Zero running due to problems during the installation process:
.
.
.
.
npm install
[email protected] install /home/pi/node_modules/bluetooth-hci-socket
node-gyp rebuild
make: Entering directory '/home/pi/node_modules/bluetooth-hci-socket/build'
CXX(target) Release/obj.target/binding/src/BluetoothHciSocket.o
In file included from ../src/BluetoothHciSocket.cpp:8:
../../nan/nan.h: In function ‘void Nan::AsyncQueueWorker(Nan::AsyncWorker*)’:
../../nan/nan.h:2298:62: warning: cast between incompatible function types from ‘void ()(uv_work_t)’ {aka ‘void ()(uv_work_s)’} to ‘uv_after_work_cb’ {aka ‘void ()(uv_work_s, int)’} [-Wcast-function-type]
, reinterpret_cast<uv_after_work_cb>(AsyncExecuteComplete)
...
...
...
gyp ERR! build error
gyp ERR! stack Error: make
failed with exit code: 2
gyp ERR! stack at ChildProcess.onExit (/usr/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:194:23)
gyp ERR! stack at ChildProcess.emit (events.js:198:13)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:248:12)
gyp ERR! System Linux 4.19.75+
gyp ERR! command "/usr/bin/node" "/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /home/pi/node_modules/bluetooth-hci-socket
gyp ERR! node -v v10.17.0
gyp ERR! node-gyp -v v5.0.5
gyp ERR! not ok
In general each communication with a register on the accelerometer requires two bytes. The first byte sent is the address of the register you wish to read or write. The second byte is either the contents you wish to write into the register, or, if you're reading, the contents of the register being sent back to the processor.
Here's a bit of code I use to set the range on the LIS331HH (This, and a lot of other register finagling are contained in the .txt document I attached to a comment in the "Data Storage Efficiancy" discussion.
// Write to CTRL_REG4 register located at 0x23 to set Full Scale and some defaults
// 1xxxxxxx Set most significant bit to one to avoid updating data registers between reading the MSB and LSB of data
// x0xxxxxx Bit for selecting big or little endian - default is 0
// xx00xxxx Sets full scale to low range
// xx01xxxx Sets full scale to mid range
// xx11xxxx Sets full scale to high range
// xxxx0000 Default values
Wire.beginTransmission(HH); // Talk to the 331HH
Wire.write(0x23); //Writes the address of the register
// Use only one of the following three statements - this assumes most signifcant bit is 1 and lower four bits are 0
Wire.write(0x80); //Set Range to LOW
//Wire.write(0x90); //Set Range to MED
//Wire.write(0xB0); //Set Range to HIGH
Wire.endTransmission(false); // false causes a restart to be sent
By default data is written into the registers as soon as it is available. This leads to the chance that while you're reading the upper byte of data the accelerometer is putting new information into the lower byte of data, and then when you read the lower byte, you end up with a pair of data bytes from two different readings. Setting the most significant bit to 1, tells the accelerometer not to be changing either byte until they are both read, (or both over written if no reading attempt was made.
Pleasantly enough, on p.31-32 of your datasheet is shows the register for setting the range has the same address and is organized in a similar manner. There are some differences, so please consult the datasheet.
Now, here is a bit of code showing how to read that same register to see if it really contains what was just written to it:
// Read CTRL_REG4 register
Wire.beginTransmission(HH); // Talk to the 331HH
Wire.write(0x23); //Writes the address of the register
Wire.endTransmission(false); // false causes a restart to be sent
Wire.requestFrom(HH, 1); // Request 1 byte
if (Wire.available() > 0){
Serial.print("CTRL_REG4: ");
Serial.println(Wire.read(), HEX); // Print the contents of the register
} else {
Serial.println("No data received");
} // End of if(Wire.available()
In the code above HH was previously defined as the address of the accelerometer:
#define HH 0x19 // Address for LIS331HH 6/12/24
Hi ladies and gentlemen!
I want to share the experience to get the code running on a Raspberry Pi 3 B in combination with a G&G JJ200B laboratory scale (German manufacturer).
Eric was a great help with the code on the Pi. More informations follow if someone is interrested.
Regards
Patrick
One reader shared some helpful suggestions about some post-processing techniques that can be used to obtain other information from the accelerometer data.
Examples:
Copy/pasted rough notes from the reader:
But integration is super simple in either script or spreadsheet. I have included a spreadsheet with 2 of your shots. X axis.
It is just accumulation. Cumulative addition of the values in your data set while subtracting the requisite offset with each addition.
This is as simple as it gets in signal processing. Nothing is simpler… besides staying home. It is the 1+1=2 of signal processing.
Assume your accel data in array a(n)
v_old=0 /forced initial condition.
p_old=0 /forced initial condition.
a offset=0.40271 (by averaging series points 6000 to 7000, rifle is totally still)
v_offset= ????? should be zero unless there are issues./Do the velocity
For i = 1 to 100
v(i)=v_old-a_offset+a(1)
v_old=v(i)
next i/do the position
For i = 1 to 100
p(i)=p_old-v_offset+v(1)
p_old=p(i)
next iThis is numerical integration of data. Not to be confused with numerical integration of a function by rectangle, trapezoidal …. Runge-Kutta or many other methods.
I am simply summing the data points.
FYI, differentiation is simply subtraction instead of addition and no offset is applied.
/home/pi/trickler/peripheral/lib/mock-scale.js:165
this._unit = trickler.TricklerUnits.GRAINS
^
TypeError: Cannot read property 'GRAINS' of undefined
at new MockScale (/home/pi/trickler/peripheral/lib/mock-scale.js:165:41)
at new SerialPort (/home/pi/trickler/peripheral/node_modules/@serialport/stream/lib/index.js:145:19)
Indeed nowhere in code TricklerUnits is even defined:
pi@raspberrypi:~/trickler/peripheral/lib $ grep TricklerUnits *
grep: build: Is a directory
mock-scale.js: this._unit = trickler.TricklerUnits.GRAINS
mock-scale.js: this._unit = trickler.TricklerUnits.GRAINS === this._unit ? trickler.TricklerUnits.GRAMS : trickler.TricklerUnits.GRAINS
mock-scale.js: case trickler.TricklerUnits.GRAINS:
mock-scale.js: case trickler.TricklerUnits.GRAMS:
As of today, acceleration data is collected as fast as possible. This means that sometimes there's a 1ms gap between samples, and other times it's 2ms. Ideally, samples should be evenly spaced.
Note: Other performance changes may be required before this is implemented. The unit could be configured to run faster, at which point, adding delays between samples will be a luxury feature.
Wonder if anyone has worked on using pwm to control the vibration motor. A few weeks back someone mentioned it in a post they made, but I cant seem to find it now, and @erichiggins has mention it a time or two. I am trying a rewrite of motor.js to use pwm as implemented in rpio. This doc is what i'm using https://www.npmjs.com/package/rpio reference. I have got the program to not throw any errors when loading but not to actually run the vibro motor. I am unsure what numbers to use for .pwmSetClockDivider (), I used 4096 which is the max allowed and gives the minimum freq of 4.7 kHz. And for .pwmSetRange I used 100, then a point you select in .pwmSetData becomes the On Time (duty cycle)
When the BT link is dropped (after Pi reset for instance), and then re-established, the target weight has not changed on the mobile app. It appears that the Pi believes the target weight is zero (default value), and it will not start working until the target weight is changed on the app, at which point I think the target weight is re-sent to the Pi and then it starts to trickle.
The connection between the Open Trickler unit (on a Pi) and the A&D scale is very flakey. The failure to connect after boot seems nondeterministic. I've had success restarting the application with pm2 restart opentrickler
, but not much else has worked.
Using what I've learned from using the mobile app for several months and hearing from others, I think a UI redesign could help solve several key issues.
The speeds of the Open Trickler are currently hard-coded.
The trickler peripheral will need to be able to adapt to a few variables:
While accounting for all of these variables, the Open Trickler should always throw the exact charge as quickly as possible without over-throwing.
One approach to resolving these issues would be to implement a PID controller.
There appears to be at least one relevant NodeJS module:
https://github.com/philmod/node-pid-controller
1.1.0
4
Issues:
Notes:
I’m using the new iPhone SE. Same screen size as the 6 which I had before.
Issue: When I view the hyperlinks in the opening page, both links come up with just blank pages.
Build information:
Any ideas what my issue is? I would like to see the logs because I am trying to dial in my motor speeds.
Thank you.
Not sure if I was supposed to start a new issue or tag along with #28.
With help from Eric I was able to get my IOS app to work ONCE. That was after I configured the scale (except for the units). It became obvious that I needed to configure the units after I tried using the app and looking at the logs. After setting the units I wasn't able to get a connection again. Eric said the serial connection needs to be good before Bluetooth can connect. Based on the logs he said it looks like the USB-to-serial adapter driver is the problem. Is the driver within Raspbian or the image? Isn't there a more robust driver out there? Shouldn't the Bluetooth connection be independent of the serial? Bluetooth is between the Pi and the app not the scale.
Another issue is the unit designator in the app only shows g even when toggled between grams and grains.
As of today, the unit records data as long as it's powered on. For the purposes of firearm acceleration, the resulting dataset also includes time between shots when nothing is happening. This non-motion data isn't particularly useful, and wasteful in other ways:
Ideally, the sensor could keep, say, 10-30 seconds of data in a FIFO buffer, That data won't be written to disk until it contains motion.
Keep in mind:
Hello guys,
I really like this project! I’m a electrical engineer but Unfortunately Im very bad in programming, I’m more a 400VAC guy... Can someone help me to re-write the code for a mettler Toledo balance? It uses MT SICS
Thanks!
With kind regards,
#trickler I'd like to branch off and make the Pi code work with an Acculab V-1mg over a similar but slightly different RS232 protocol.
What files and variables would control both the RS-232 comms setup and message definition / decoding?
Sorry for being dense, but I am not figuring out how to test the IOS App. I have TestFlight installed on my from, but where do I (or how do I) get an invitation code.
Thanks
Have a questions about the new image, and a question about an Improvement?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.