Comments (10)
Thanks for the report. I have attempted to debug the issue but can't recreate it. Can you give me some details, such as:
- JMRI version
- JMRI panel file / screenshots of the sensors, signals, turnouts, etc in the tables menu
- Arduino model being used
- What version of Arduino software
- OS
- Where you are seeing the error messages
- Steps to recreate the issue
- How the turnout causing the error is set up
As for imaginary bits, could you post the sketch that is exhibiting this behaviour? I haven't come across this issue before, so I'd be keen to get to the bottom of it.
from arduinocmri.
Update: According to the JMRI devs, those console errors mean that JMRI is expecting a reply, but didn't receive it in time. The use case for this is a homemade indexing system for an Atlas turntable (you know, the one that's been around forever and is a total pain to DCC) so I suspect the problem is that the Arduino is waiting on the turntable to finish rotating when it should be handling CMRI stuff. I'll post the full sketch/JMRI information shortly, but I wouldn't be surprised to find out that's where the "imaginary bits" are coming from and that it's not an inherent fault in your library.
from arduinocmri.
Arduino Sketch
The Arduino sketch can be found on my turningTables Repository. I am using Arduino IDE 1.6.7 with an official Arduino Uno (on a USB 2.0 port, if that matters) on Ubuntu GNOME 16.04 amd64.
Most of the sketch has to do with hardware/motor stuff, so here is a "condensed" version:
void setup() {
//set all the pins to the correct mode
pinMode(motor_cw_pin, OUTPUT); //motor clockwise
pinMode(motor_ccw_pin, OUTPUT); //motor counterclockwise
pinMode(hall_pin, INPUT); //hall effect sensor input (used as a tachometer)
pinMode(service_btn_cw_pin, INPUT_PULLUP); //these buttons are for calibrating the turntable
pinMode(service_btn_ccw_pin, INPUT_PULLUP);
//read EEPROM for last position
EEPROM.get(0, currentPosition);
//making hall effect sensor interrupt
attachInterrupt(digitalPinToInterrupt(hall_pin), hallTrigger, FALLING);
//start Serial connection for CMRI
Serial.begin(9600, SERIAL_8N2);
//set last bit states initially - this is part of my hacked together system for detecting if a bit changes
for (int i=0;i < 47;i++) {
lastBitStates[i] = cmri.get_bit(i);
}
//play startup noise - this is just so I know when the turntable is ready, it plays on a little piezo speaker. it does use delay()
startup_beep();
}
void loop() {
//This code handles reading the alignment buttons. The buttons move the turntable not one track position, but one rotation of the measured gear, which is useful if the mechanism gets a few turns out of alignment.
buttonState_cw = digitalRead(service_btn_cw_pin);
if (buttonState_cw != lastButtonState_cw) {
if (buttonState_cw == LOW) {
click_cw();
}
}
lastButtonState_cw = buttonState_cw;
buttonState_ccw = digitalRead(service_btn_ccw_pin);
if (buttonState_ccw != lastButtonState_ccw) {
if (buttonState_ccw == LOW) {
click_ccw();
}
}
lastButtonState_ccw = buttonState_ccw;
//end button handling code
//CMRI interface code
cmri.process();
//all the bits for the stalls - there are 24 stall tracks so we read all those bits here
for (int i=0; i < num_tracks; i++) {
int currentBit = cmri.get_bit(i);
if (currentBit == 1) {
if (currentBit != lastBitStates[i]) {
rotate(i,0); //this is the tricky part. this function does not complete until the turntable is done rotating, so you can imagine this can take a little bit.
}
}
}
//bit 25 is supposed to rotate the turntable 180 degrees. This is also a problem area as this function often gets called several times (I think because of the time it takes to complete screwing up the timing of the CMRI data tx/rx) which is useless because then the turntable just does a full 360 (or more) instead of a 180.
if (cmri.get_bit(25) == 1) {
if (cmri.get_bit(25) != lastBitStates[25]) {
turn_ccw(12);
}
}
//set last bit states at the end of the "cycle".
//this goes along with my makeshift "is this bit changed?" system.
for (int i=0;i < 47;i++) {
lastBitStates[i] = cmri.get_bit(i);
}
}
If you need more information about any of that I can answer questions. I'm new to C in general so my commenting/organizational skills are probably a little lacking.
JMRI/PC Info
PC Specs:
- Ubuntu 16.04LTS amd64
- GNOME Desktop
I do not have a panel set up for this project yet, so I just included screenshots of the turnouts table and the JMRI version info.
The turnouts are set up as steady-state output, 1-bit turnouts. There are no Logix set up for them.
If I throw the "Turn 180 degrees" turnout, sometimes it will be called 1 time, sometimes several times. This doesn't make a difference with the other turnouts because once it's at that position, the rotate()
function in the Arduino code simply finds that 0 moves are required to get to the desired position, and it does nothing. But with the "turn 180 degrees" turnout, it can just keep running over and over again. I haven't narrowed down the "imagining bits" issue to specific steps (yet) but it frequently will turn to a stall track that corresponds to a bit that isn't even configured with JMRI as a turnout, and this happens randomly, but especially frequently after throwing the "turn 180 degrees" turnout.
from arduinocmri.
I'll do some tests tonight, but I believe the issue might be due to the turn_cw
and turn_ccw
functions being blocking. So while the turntable is turning, it is so busy checking its position that no CMRI messages are processed. Once it finishes turning, the queued up messages (sitting in the Arduino's serial buffer) get processed. These messages are almost certainly POLL requests, resulting in a bunch of GET replies being sent out (41 52 ...
) when JMRI isn't expecting any; it only expects a single GET message in response to each POLL message that it sends out.
While these unexpected messages won't hurt JMRI, it will cause it to complain. Do you have any sensors set up? Can you show the output of C/MRI > List Assignments?
from arduinocmri.
Just seen your earlier message; seems the JMRI devs came to the same conclusion as me. You'll need to convert your code to set a target value for the motor, and then check that each time through the main loop. It's not too complicated to do, just requires a different way of looking at the logic.
The other option is to not have any CMRI sensors set up; then JMRI won't send out POLL requests for it.
from arduinocmri.
Okay, sounds good, I'll try that and let you know if that fixes it. Out of curiosity, how long does it typically take to run cmri.process()
?
from arduinocmri.
It varies depending on whether there is a POLL message that needs responding to or not. If there is no data to process, it is near enough to instant. If it needs to send out a poll response, then it'll take fractionally longer, but it shouldn't be significant.
from arduinocmri.
I just finished rewriting the rotation system to be non-blocking. After some tinkering (which had less to do with your library and more to do with my limited C experience) I was able to get it working with JMRI. The only blocking thing in the program now is the initial startup_beep()
function that runs at the very end of setup()
, and plays a quick series of notes on a piezo speaker to let me know the controller just booted up. Everything seems to work! A couple times I have gotten one of those errors in JMRI immediately after the board starts, so I think that's due to the startup_beep()
function being blocking. In an hour or so of testing I was not able to reproduce any of those errors by throwing/closing turnout bits, which is what caused them before.
So in short, this was my fault for not writing everything to be non-blocking. Thank you so much for your patience and for your help with this program. I really appreciate it!
from arduinocmri.
Awesome glad to help. So the random toggling of lines has gone away too?
from arduinocmri.
Seems to. The only thing that I have not gotten totally working is the "turn 180 degrees" function, which sometimes gets called twice, but if I do it in a strange way it works fine. I'm pretty sure that's issues in my programming.
from arduinocmri.
Related Issues (10)
- Out of bound checking leads to buffer overflow HOT 1
- The process function does not return the packet type processed
- Unable to load ArduinoCMRI library to the Arduino Web editor
- Delay in transmit prevents usage
- Curious about porting this project for Energia (TI MSP430 Launchpad Family) HOT 7
- Uno support: according to JMRI devs it should work HOT 4
- Bits other than 0 not working? HOT 1
- Compiling error message in Arduino IDE HOT 3
- Example RS485 code not working? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from arduinocmri.