MCP2515 CAN BUS controller seems to conflict with writing to SD card?
bgp
Posts: 34
I have a CAN BUS Shield from SparkFun and am talking to it from a Propeller project board, trying to make something that will log diagnostic messages to an SD card so I look at them offline. I'm interfacing with the MCP2515 using SPI and have code written using PropWare and although I haven't actually plugged it into a car yet the library does seem to be talking to the chip and I can send messages in loopback mode and get them back - everything seems golden up to this point.
But, when I add logging to the SD card to the setup, all interactions with the MCP2515 start returning errors after the first call to fopen() to open the file to start logging.
For the SD card I'm using one of these OSEPP shield things.
The voltages are a bit interesting, as the CAN BUS Shield and the OSEPP SD shield both require 5v power and I have a separate regulator and capacitor for each to give the stable power. (At first I thought that maybe using the SD card was causing a power dip and browning out the MCP2515, which I guess it still possible but I don't see how.)
The basic connections are: Prop pins 0-3 are SPI for SD, connected directly; Prop pins 13-16 are SPI for MCP2515 with a 2k resistor in series on the MISO pin (and this has worked and I confirmed I get messages back from the chip with this setup).
And the offending snippet of code (C++) looks like:
I haven't looked at the raw bits/signal that the MCP2515 returns after it starts freaking out, which I will do as soon as I can, but I'm guessing it's either gibberish or all the same bit - i.e. the chip is not in a valid state.
Does anyone know what I might be missing here? Kinda stumped.
But, when I add logging to the SD card to the setup, all interactions with the MCP2515 start returning errors after the first call to fopen() to open the file to start logging.
For the SD card I'm using one of these OSEPP shield things.
The voltages are a bit interesting, as the CAN BUS Shield and the OSEPP SD shield both require 5v power and I have a separate regulator and capacitor for each to give the stable power. (At first I thought that maybe using the SD card was causing a power dip and browning out the MCP2515, which I guess it still possible but I don't see how.)
The basic connections are: Prop pins 0-3 are SPI for SD, connected directly; Prop pins 13-16 are SPI for MCP2515 with a 2k resistor in series on the MISO pin (and this has worked and I confirmed I get messages back from the chip with this setup).
And the offending snippet of code (C++) looks like:
// THIS ALWAYS WORKS int sdret = sd_mount( SDCARD_DO, SDCARD_CLK, SDCARD_DI, SDCARD_CS); // PropWare setup for MCP2515 SPI const SPI spi(MOSI, MISO, SCLK); MCP2515 can(spi, CS); // IF I COMMENT THIS LINE OUT THINGS WORK FINE, OTHERWISE THE can.start() BELOW ERRORS FILE* fp = fopen("proplog.txt", "a"); can.start(MCP2515::BaudRate::BAUD_1000KBPS)
I haven't looked at the raw bits/signal that the MCP2515 returns after it starts freaking out, which I will do as soon as I can, but I'm guessing it's either gibberish or all the same bit - i.e. the chip is not in a valid state.
Does anyone know what I might be missing here? Kinda stumped.
Comments
FYI: none of the code you're using so far (SPI, SD, Fat*, MCP2515) use their own cog. That means you can either simplify your board by combining the SPI buses, or increase your performance by running the SD+FAT code in a separate cog from the MCP2515 code.
After trying a few things the only (somewhat) educated guess I can make is that I was overflowing the stack and things are going haywire because it. I've noticed that somewhere around 31500 (maybe a bit less) as a built image size will cause all kinds of strange things to happen. And then I'll comment out some separate unrelated functionality and it's library and it will drop down to 30000 or so - and the same code that was just failing now works fine. I've tried this 3 or 4 times and it's fairly reproducible.
Do you happen to have any tips on reducing the output size? On this project when I include code for CAN bus interaction via MCP2515, logging via SD, and LCD display (HD44780), the image size is somewhere around 34k and it of course doesn't load.
(Or I guess switching to a memory model that supports external storage, assuming that is feasible, is a possibility as well, although it seems overkill for what I'm doing.)
(Only catch I can see is if the runtime speed somehow makes a difference - apparently CMM is slower. But I don't think so, the only possible caveat I see is if I lose messages off the CAN bus by not retrieving them fast enough because the code now runs slower and the MCP2515 will only buffer I think 3 or something before it throws them away - but I doubt that will be a significant issue, if an issue at all.)
I'm thrilled to hear you're getting so much use out of PropWare's classes. Care to share exactly what you're building?
A client of mine sells devices that plug into the OBD port of your car along with a related service and online platform. They want to be able to do a test on each device and make sure it does it's thing properly before they ship each one out the door. I believe all that is needed is for the device to "detect that a car is present" and it will initialize itself and the person doing that can see that all is well and it's done. Right now they literally walk out to the parking lot and plug the thing into a car to test it, or they recently bought one of these simulators and that works as well. The problem is that it's not very cost effective as you scale up - the simulators are easily $150 a pop. So I'm essentially trying to build just enough of one of these simulators in software (recording the bus chatter from a car and playing it back is probably fine - I'm hoping it's that simple).
I'm doing a prototype for now with an LCD and SD logging, but the final will just be a big board with a dozen or two OBD ports on it and I'll probably drive 4-5 of them with one propeller project board. And yes, it's all using PropWare - which is awesome!
--
As another interesting note: Even with the smaller code size I still ran into odd stack issues; and the fix was to move variables (specifically the larger classes/structures) out of the main function and make them global - thus removing them from the stack. This is a workable fix but it was not easy to figure out. I also couldn't find out how to change the stack size associated with the main function (I know that when you start new cogs you give it a specific stack space to use, but I'm not sure how the stack size for cog 0 is chosen; I assume it's a compiler/linker flag of some sort but I haven't found it yet.)
I ran into something _very_ strange in the course of this. I stripped it down to a simple demo program and made a video (it's only 2 min). When you have a sec can you please take a look and see if you have any idea what might be happening here: (link: youtu.be/opC-Iec6OAE ): (TL;DR: a small program compiled with CMM exhibits buggy behavior but works in LMM.)
I've been running into this phenomenon quite a bit. The behavior seems deterministic for each build, i.e. the same exact source, compiled and run over and over will produce the same output each time. But when I do some small innocuous change like adding or removing a log line, the program will then exhibit some additional piece of strange behavior - everything from randomly freezing to garbled console output, etc.
(FYI: Just tried the same experiment - same source code line for line - building through SimpleIDE and the result was exactly the same. Also, PropWare version: 3.0.0.132)
-Brad
Also, just FYI, you never have to manually re-invoke CMake after the first time. The first dependency that CMake writes in the Makefiles is on the CMake files, so if they ever change, then the Makefiles get auto-regenerated
P.S. http://david.zemon.name/downloads/ looks browsable; if not what you intended, adding:
Options -Indexes
to a .htaccess file in that folder should fix it.
Here's what I run from TeamCity. If you could replicate that, I'd be greatly appreciative:
Once you have the package, either you can upload it somewhere that allows me access, or I can create a temporary, restricted user for you to SCP the file directly onto my server.
I built this on my Mac (since it's not going to work for me to mail it to you
Here's the final output: https://www.dropbox.com/s/dayb8nfhvqque7c/propellergcc-alpha_v1_9_0-osx.tar.gz?dl=0
I did just a quick test and it does not appear to have different behavior than the existing compiler I'm using from the stock SimpleIDE download.
For now, since I at least understand more about the problem, I was able to work around things by going back to LMM and not using the FAT FS code but instead just logging directly to the SD (the FAT code is ~10k, which makes a very big difference). Not the greatest solution in the world, but it'll work for now.