29 Jun 2007

Since I had yesterday and today off, I spent it cleaning up and finishing the CAN code, finally. The code is 100% working (save for any bugs that may come up) attached is a tar ball that has 3 directories, sensor_node, test_node and can_lib sensor_node has a main.c and whatnot that handles reading from a sensor on adc port 0 test_node just simply waits to receive a value from the can network, then turns on an led attached to pdc1 can_lib is the library for linking to.

Xander, since you are better at the C stuffs, should we turn this into an actual library, that we can link against? Can you do that if so? I don't remember how to do that stuff. Include in the directories are a make file that maybe you can use to do this quickly. whatever though.

Included in this release are! * full can read/write support * support for filtering * support for interrupt receives * support for polling receives

You shouldn't need to do anything with the actual library, just put in the required includes, and follow the steps below in my jun 20th post. Let me know if you have any issues. word.

20 Jun 2007

Attached is another release of the can stuff. Note I've just been working on this at work today, and haven't even built it yet, but the test_node is quite a bit cleaned up and I think I have the interrupts working on it, etc,etc,etc. Also, I've only really cleaned up the main.c in test_node

Heres a little bit of documentation to go with it. hoorayz.

To boot up the mcp2515 there are 5 calls, in the following order
note that you also currently need the uart_init call, but we can tear that stuff out later

sei - enable interrupts obviously
spi_init() - initialize spi obviously 
can_init(speed, is_extended, filter) - init the mcp2515 at specified speed, and filter (is_extended is whether it is an extended id filter, or a standard id filter)

mcp2515_setCANCTRL_Mode(MODE_NORMAL) - set mcp2515 to normal mode (send and receive)
Now the can controller is ready to send and receive traffic. awesome and easy! Next we need to turn on the interrupt.
// turn on the rx interrupt:
EICRA = 0; // set the interrupt on low level triggered for int0 and int1
EIMSK = 1; // enable int0 (PB0)

Next you must write an interrupt handler, attached to a specified interrupt pin, such as:

ISR(PCINT0_vect)
In this interrupt handler you must write a loop that reads in all of the can messages and does something with them:
   while ( can_readMessage(&msg) == CAN_OK ) { 
where &msg is a CanMessage? struct
then you can access the msg.identifier, msg.data[8], and msg.dlc to read the identifier, data and data length respectively

After that loop is done, we read in the CANINTF register, which tells us if any of the RX buffer full flags are set and if they are, we clear them:

  canintf_reg = mcp2515_readRegister(MCP_CANINTF);
   if(canintf_reg & 1)
      mcp2515_modifyRegister(MCP_CANINTF, 1, 0)
   if(canintf_reg & 2)
      mcp2515_modifyRegister(MCP_CANINTF, 2, 0)

Thats pretty much all we need to do for receiving.

Now if we want to send a message we do something like the following (init stuff sending is the same as receiving, save for that if you are only sending you don't need the interrupt handler)

// create a CanMessage struct:
CanMessage msg;
// initialize the msg struct:
can_initMessageStruct(&msg);
// set the identifier
msg.identifier = S1L1; // sensor 1 leg 1
// define if it is an extended or standard message (0 for standard, 1 for extended)
msg.extended_identifier = 0;
// define how many data bytes we are using:
msg.dlc = 1;
// set the data:
msg.data[0] = 255;
can_sendMessage(&msg)

13 june 2007

Here's where I am at (i'll put this in adamspace on the wiki too): I have filtering working, I was mistakenly sending with standard id and trying to filter on an extended id, or vice versa, but now it seems to work. I discovered this while trying to document/clean up the code a bit, so I'll finish that up tonight hopefully and get it posted to the wiki.

Friday night, I will be up around 9:30 or 10 if all goes as planned (when does driving to seattle go as planned, though). Should I get dropped off at xander's house? Will you be home and willing to work on stuff that late? Is Art going to meet us as well?

I'm also going to bring up this big spool of cable, and I have a can + atmega168 board that I'm working on that maybe we can finish, although its pretty crappy, so maybe we should just make a new one. whatevz tho.

I am laying out a board for the can controllers since I am pretty sick of soldering jumper wires. pain. in. the. ass. I have this mostly done, but I'm just trying to lay it out prettier and then I have to make sure that everything is going to the correct places. Hopefully I'll get that sent out on Friday or something to batchpcb. Maybe we can go over it friday night together and make sure everything looks good. I don't wanna order 15 of these boards and then have a major design flaw and have to order another 15.

Soon, I plan on working on a leg lighting prototype. Should be pretty easy, just some pwm and some mosfets and whatnot. I have 10 ea of R G and B leds that I'll be using for this, so it should be pretty decent. I've decided that the enclosure will be made out of wood, with holes drilled through it for the leds. I have some plastic led mounting things from besthongkong.com that should work decently i hope. I'm hoping I can get my dad to make these boxes for me, since he has power tools and what not.

Anything else you need from me?

5 may 2007

I finally have all the stuff for making the CAN controllers for Xander, I'll have those done this week. I believe Seth is visiting me this weekend, so I'll hand them off to him. I am spending 1500 dollars on getting a root canal & crown, so I wont be able to spend much on the project for the next month or so. Fortunately, I have most everything I need for my prototyping and development stuffs, so I shouldn't need to spend too much money for the next month or so anyways.

After this tooth, I have 2 more root canals & crowns, plus some other tooth stuff I need to get done before burning man, lest I want to get an abcessed tooth in the middle of nowhere. hooray for not having health insurance.

2 apr 2007

Some thoughts on the CAN stuff: Each packet has the following two items that we need to pay attention to in designing a layer 7 protocol: * each packet has an 11 bit identifier (optionally an extended 19 bit identifier) (I am thinking of using the 19 bit identifier, but only 16 bits for simplicity.) * each packet has 8 bytes of payload * CAN is a multicast bus architecture

The basics of designing any kind of layer 7 stuff for this (from my thoughts): * hash out what kind of data we need to send/receive.

    • This will form the basis for the identifier. For example: say we need each solenoid to be individually addressable, we could assign them identifiers 0x10, 0x11, etc, we can then put how fast or whatever they should dip into the water in the payload of the packet.
    • Put this all into an include file: #define SOLENOID_1 0x10, etc
* in the CAN init routine, we will pass it an array of what identifiers we will be receiving. The CAN controllers have filters for this already, but there may not be enough, so we may just do all the filtering in software since this isn't too difficult * the CAN receive interrupt will, when receiving a packet with an identifier it likes, place it into an circular linked list, and two variables will be kept up to date by read and write (recvHead, recvTail respectively). How many items will this need to hold? What happens if recvTail catches up to recvHead, should we just start overwriting? Maybe we can make it grow if need be? Is managing a linked list to the point if automagically growing a little above the power of the microcontroller? * in receive code, you will read from this linked list whenever you can, and process the data accordingly. Retrieving data out of the linked list will be a function call that will automatically update the recvHead ptr and return a struct containing: uint16_t identifier, uint8_t[x] payload, and uint8_t dataCount.

Thats all my thoughts for now. I'm not sure that I"m going to bring up the CAN modules to Xander yet. I only have enough parts right now to make two, which means that I can't work on it myself : ] (well, actually I have all the parts but the perfboards, so if I can make it to somewhere to pick up a couple of those this week and find the time to make 2 more (since I have one fully working now) then I'll bring 2 up to him.

Xander sez

As far as the addressing goes, I can't see how we're going to need anything more complex than a simple bus topology for the entire system. I presume the CAN controller chips filter addresses at a hardware level so our individual subsystems won't receive interrupts for packets that weren't addressed for it. If so then really there's no need for even multicast addressing and we can simply address everybody via unicast.

Here's a simple mockup of the image in my head: Control_diagram.png

As for what to do in the case of buffer overruns, we should probably drop older data to make room for newer and try to avoid splitting messages over multiple packets wherever possible.

Adam sez:

Agreed on that we want a unicast architecture. The extended identifiers are actually 29bits. Those are the ones we will be using. The CAN controller supports, in hardware, 6 * 29 bit filters, and 2 * 29 bit masks. Previouslly I hadn't noticed that there were masks, which was why I was thinking of doing this all in software. We should be able to assign a mask to each system, but have the mask be just the first 8 bits of the identifier. Then we can use the rest of the identifier for internal protocol routing. so say 0x1100 for the main light's mask. then when addressing the main lights green channel for changing a value, we'd do 0x1101, or 0x1102 for red, or 0x1103 for blue or what not

The way that the masks and filters work are: if mask bit n = 0: identifier bit n passes if mask bit n = 1 and filter bit n = 1 and identifier bit n = 1: identifier bit n passes if mask bit n = 1 and filter bit n = 0 and identifier bit n = 0: identifier bit n passes all others fail

I don't see anywhere that we will have to split data over multiple packets, so I don't think we need to worry too much about that.

Xander sez

I had a look at the mcp2515 specs and I'm curious, why are we going with the 29-bit extended addressing scheme? The standard 11-bit addressing would give us room for 2048 different entities on the network with enough flexible masking to group them in any conceivable configuration I would think. For instance there's only going to be 47 LED's on the main board in the current configuration, 8 caustics generators, and unless you're planning on having just shy of 2000 individually CAN-controlled structural lights (xmas squid o'd00m!@#$) it seems 2048 would be enough?

Adam sez

Because the filters/masks have to be 29bits long, so if you go with the 11bit addressing, then the 2515 uses 2 out of the 8 bytes for the filter mask compare. This might be fine in general, though, as 6 bytes of data for each packet might be enough. I haven't really thought too much about/started to implement this yet. Thats what i'm going to work on this weekend. we can just use 11 bytes of the filter and have the last 18 bits of the mask be 0, i suppose, this is pretty much what I was planning on with the 29bit identifier anyhow.

I was actually only probablly going to use 8 bits, out of the 29 bits for the identifiers, since i really doubt we need more than 256 individually controlled doo-hickies. How are you planning on doing the LEDs? Are you going to have multiple red/green/blue channels to identify? or is it all just going to be one channel of each that are identifiable? We talked about just having a function that my sensors feed into that control all the different aspects of the system in an organic way, are we doing that? If so, then we probably just want to address the lighting controller, and the caustic controller, and have the ID be a sender-id for each controller to filter on. So you'd have each sensor have its own ID that the receiver filters on. The receiver then would figure out what to do with that sender's data. if that makes sense.

Anywho, for now I've just got to work on getting the interrupts working and what not. Once that is going we can talk more about the packet sizes, etc.

Xander sez

Yeah, that's pretty much how I read the specs, that when using 11-bit addressing the first two bytes of data are considered in the mask but that certainly doesn't mean you have to use those bytes. You simply configure the filter to not care what the first two data bytes are set to and you're gold. If that was the only reason then I think we should go with the 11-bit addressing scheme since that will reduce the total frame length on the wire and let us cram more data on the wire or, more importantly, possibly reduce the overall transmission rate (haven't looked if that is possible) in order to boost noise immunity. From the way things have been specing out, I have a feeling we may have more bandwidth than we can shake a stick at.

As for addressing, my current feeling is that we're simply going to have one address for the LED controller and another for the caustics controller. I'm not 100% on this and may go back to the idea of packing some of sub-system data into the address field, but either way it shouldn't affect the rest of the system much. By no means do I think we should have the various sensors and stuff talking directly to the other subsystems simply due to the software design headaches and troubleshooting complexities that would entail. I want to keep the individual system controllers as simple and stupid (read: bullet-proof) as possible. I don't want to have to fix a microcontroller code bug out in the field.

As far as the whole control in general, I've been going with a monolithic design in mind. All sensors report back to a master controller which does all the computation and controls everything. I'm thinking that the master controller will be a single-board computer running a unix of some variant, possibly even with WiFi? so we can tweak things wirelessly with a laptop. Since the master controller doesn't speak CAN, it'll need a CAN interface helper which will simply be another microcontroller which interfaces with the CAN network and uses it's UART to talk bidirectional RS-232 to the master controller. The master controller will live in the 'not a breaker panel'.

1 apr 2007

Word. I have communication to the CAN controller IC, and what not. And I have most of a module soldered up. At this rate I should hopefully have 2 to bring to Xander next weekend, although the code may not be all the way there yet, but at least he'll have them to mess around with and what not once I get the code completed.

I haven't yet gotten data transmitted between two of these things, but thats fer totez coming soonish i think.

update

woot. i think i have succesfully transmitted an 'a' across the CAN network.

22 Mar 2007

meh. I don't think i'm going to have this ready this weekend, but hopefully the next time I'm up. Possibly in 2 or 3 weeks.

I got an stk500 finally, so I can start working with fer really realz avr, rather than just the introductory level arduino board. Its kind of a learning curve so far, but i'm getting places.

I think I'm going to make CAN controller boards for each individual project (1 for each of the sensors, one for the main light, etc), these will then plug into the host board via some kind of ribbon cable or what not. This will make it easier for Xander as he wont have to incorporate the CAN circuit into his board design, he will just need a few pins pinned out to a header for spi (PORTB handles SPI, so keep that in mind for you code design, and let me know if that stomps on anything you are doing).

The mcp2515 takes ~5 or 6 pins to work with (SCK, MOSI, MISO, INT, and CS (maybe RST as well)), plus power and ground. So maybe keep in mind an 8-10 pin header for board designs. Although I don't see it as an issue, if using 7 pins (probablly all of PORTB basically), is too much to ask for, they do have 2 pins that can be used as general purpose output on the MCP2515. You just call serial commands to turn them high or low. I don't want to go through the trouble of getting this to work, though, if I don't have to.

Another design thing to note is that I don't know if CAN requires all items to have a shared gnd. Although I suppose maybe they will inherently since its all coming from the same power source? If we use DB9 cables, we should be able to run power and gnd down the unused pins (since we only use 2 for CAN). I'm not sure how much power a DB9 cable could support though? We don't need nearly as much for the Arch lighting as the main light, but we will need a bit. Xander any ideas on this?

word is bond. crackuhz!

13 Mar 2007

I found an AVR library for the CAN stuffs. So hopefully I can get that working in the next week or so and bring a couple of CAN circuits to Seattle and drop them off somewhere for Xander to play around with. Its pretty crazy shiz, but hopefully this library will make everything easier.

The end. dood.

-- AdamB - 13 Mar 2007

Topic attachments
I Attachment Action Size Date Who Comment
ziptgz psyphozoa_can.tgz manage 106.2 K 29 Jun 2007 - 19:39 AdamB can stuff - 6/29
zipzip psyphozoa_can.zip manage 456.8 K 20 Jun 2007 - 20:30 AdamB can stuff - 6/20
Topic revision: r15 - 29 Jun 2007 - 19:39:46 - AdamB
 
This site is powered by the TWiki collaboration platformCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback