# CON-bus Getting Started

# Getting Started with CON-bus

## Loading the example
After following the [Arduino Installation](https://wiki.soonerrobotics.org/books/firmware-development/page/arduino-installation) instructions, you should see `CON-Bus Lib/CAN_Example` available in the Examples menu under `Examples from Custom Libraries`.

## Code Explanation
```
#include <CONBus.h> 
#include <CANBusDriver.h>
#include <ACAN2515.h>
```
First, we include all of the necessary dependencies. For the example project, we are using the MCP2515 CAN Controller Driver and so import `ACAN2515.h`.

```
ACAN2515 can(MCP2515_CS, SPI1, MCP2515_INT);

// Setup CONBus variables
CONBus::CONBus conbus;
CONBus::CANBusDriver conbus_can(conbus, 42); // device id 42
```
Here we construct the ACAN2515 object to communicate with the MCP2515 chip. We also construct the main object used by CON-Bus: `CONBus::CONBus`. This object holds all the features of the CONbus library. Finally, we also construct a `CONBus::CANBusDriver` object and pass it the `CONBus::CONBus` object we created earlier. We also pass it a device ID which identifies this specific CONBus device (see the CONbus specifications for more details on CONbus ID).
```
bool useOven = false;
int numberOfOvenRacks = 0;
float ovenTemperatureSetpoint = 100;
```
```
// Create CONBus registers
// The addresses can be anything from 0 to 255
conbus.addRegister(0, &useOven);
conbus.addRegister(4, &numberOfOvenRacks);
conbus.addRegister(21, &ovenTemperatureSetpoint);
```
Here, we create three variables of different types and register them with our CONbus object. By passing the variables by reference to the `addRegister` method, the CONbus library will automatically change the variables without any additional work from the developer.

```
void onCanRecieve() {
  can.isr();
  can.receive(frame);  

  conbus_can.readCanMessage(frame.id, frame.data);
}
```
Skipping to the bottom of the example, we can see where we setup `onCanReceive()` which is an interrupt called every time our ACAN2515 driver receives a CAN message. With just one line, we pass the CAN message into our CONbus CAN driver object. The CAN driver will automatically handle checking if the message conforms to the CONbus spec and modifying any variables registerd with CONbus.

```
void loop() {
  if (conbus_can.isReplyReady()) {
    conbus_can.peekReply(outFrame.id, outFrame.len, outFrame.data);

    bool success = can.tryToSend(outFrame);

    // If we successfully send the message, remove the message from the queue
    if (success) {
      conbus_can.popReply();
    }
  }
}
```
Finally, in the Arduino `loop()` method, we continously peek our CONbus CAN driver object to see if there are replies waiting from CONbus to be sent back out over CAN to other devices. For example, these if another device requests a register's value then the CANbus library will generate a reply and store it in the CAN driver until sent. In the above code, we check if a reply is ready, read its value, and attempt to send it out over CAN. If the send was successful, we pop the reply out of the CAN driver so it knows it has been sent.