diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..0f0d740 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ] +} diff --git a/README.md b/README.md index b88e9b7..4ae420f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ # CanTestProject -CAN Bus Test Project \ No newline at end of file +CAN Controller Testprojekt mit zwei Arduino MEGA, MCP2515 Can Modulen als Ausgabe eine GLCD und eine LED Matrix. + diff --git a/include/README b/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..8e9e0e8 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,21 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:megaatmega2560] +platform = atmelavr +board = megaatmega2560 +framework = arduino +lib_deps = + seeed-studio/CAN_BUS_Shield@^1.20 + Wire + SPI + arkhipenko/TaskScheduler@^3.2.0 + olikraus/U8g2@^2.28.8 +monitor_speed = 115200 diff --git a/src/glcd_test.cpp_ b/src/glcd_test.cpp_ new file mode 100644 index 0000000..1f34be6 --- /dev/null +++ b/src/glcd_test.cpp_ @@ -0,0 +1,47 @@ +#include +#include + +#ifdef U8X8_HAVE_HW_SPI +#include +#endif +#ifdef U8X8_HAVE_HW_I2C +#include +#endif + +#define Gu8g2_CS_PIN 48 +//U8G2_ST7920_128X64_1_HW_SPI lcd (U8G2_R0, Gu8g2_CS_PIN); +U8G2_ST7920_128X64_2_8080 lcd(U8G2_R2, 5, 6, 7, 8, 9, 10, 11, 12, 4, U8X8_PIN_NONE, 3, 2); + +void setup(void) { + lcd.begin(); + +} +uint8_t m = 24; + +int lcd_welcome_count = 0; +int lcd_screen = 0; +int wert1 = 137, wert2 = 28495; + +void loop(void) { + if (lcd_welcome_count < 3) { + lcd.firstPage(); + do { + lcd.setFont(u8g2_font_10x20_tr); + lcd.drawStr(0,30,"CAN Test"); + lcd.drawStr(48,50,"Project"); + } while ( lcd.nextPage() ); + lcd_welcome_count++; + } else if (lcd_screen == 0) { + lcd.firstPage(); + do { + lcd.setFont(u8g2_font_6x10_tr); + lcd.drawStr(13,9,"CAN Test Project"); + lcd.drawLine(4, 12, 124, 12); + char buffer[10]; + lcd.drawStr(5,23, "Wert 1: "); lcd.drawStr(48,23, itoa(wert1, buffer, 10)); + lcd.drawStr(5,34, "Wert 2: "); lcd.drawStr(48,34, itoa(wert2, buffer, 10)); + } while ( lcd.nextPage() ); + lcd_welcome_count++; + } + delay(1000); +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..c58b0da --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,233 @@ +#include +#include +#include "mcp_can.h" +#include +#include + +#define debug +#define CAN_CS_PIN 49 +#define CAN_SPEED CAN_500KBPS +#define GLCD_CS_PIN 48 + +Scheduler task; +MCP_CAN CAN(CAN_CS_PIN); +U8G2_ST7920_128X64_1_8080 lcd(U8G2_R2, 5, 6, 7, 8, 9, 10, 11, 12, 4, U8X8_PIN_NONE, 3, 2); + +#define Solarpanel_width 64 +#define Solarpanel_height 56 +static unsigned char Solarpanel_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x88, 0x07, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1f, 0x7c, 0x08, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x90, 0x0f, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x70, 0x10, 0x18, 0x00, 0x00, 0x00, + 0xf0, 0x18, 0x0e, 0x10, 0x1e, 0x00, 0x00, 0x00, 0x0e, 0xf0, 0x09, 0xe0, + 0x21, 0x00, 0x00, 0x00, 0x02, 0x1e, 0x10, 0x78, 0x40, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x10, 0x4f, 0x40, 0x00, 0x00, 0x00, 0x04, 0x03, 0xf0, 0x80, + 0xf0, 0x00, 0x00, 0x00, 0xe4, 0x02, 0x38, 0x80, 0x0d, 0x01, 0x00, 0x00, + 0x18, 0x84, 0x47, 0x80, 0x03, 0x01, 0x00, 0x00, 0x08, 0x6c, 0x40, 0x60, + 0x01, 0xf2, 0x0f, 0x00, 0x10, 0x18, 0x80, 0x18, 0x82, 0x01, 0x10, 0x00, + 0x10, 0x08, 0x80, 0x07, 0x64, 0x00, 0x20, 0x00, 0x10, 0x1e, 0xc0, 0x01, + 0x1c, 0x00, 0x20, 0x00, 0xe0, 0x11, 0x30, 0x01, 0x06, 0x00, 0x20, 0x00, + 0x20, 0x20, 0x0c, 0x82, 0x01, 0x00, 0x20, 0x00, 0x40, 0xa0, 0x03, 0x62, + 0x00, 0x00, 0x20, 0x00, 0x40, 0xc0, 0x00, 0x1c, 0x00, 0xf0, 0xff, 0x3f, + 0x80, 0x70, 0x00, 0x07, 0x00, 0x10, 0x00, 0x20, 0x80, 0x8c, 0x80, 0x01, + 0x00, 0x10, 0x00, 0x20, 0x80, 0x83, 0x60, 0x00, 0x00, 0x90, 0x4b, 0x2f, + 0x00, 0x00, 0x1d, 0x00, 0x00, 0x50, 0x48, 0x21, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x50, 0x48, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x78, 0x2d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x48, 0x29, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x50, 0x48, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x4b, 0x2f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0xe0, 0x01, 0x78, + 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x02, 0x84, 0x00, 0x10, 0x00, 0x20, + 0x00, 0x10, 0x02, 0x84, 0x00, 0xf0, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x20, 0x00, + 0x80, 0x01, 0x00, 0x00, 0x18, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x00, 0x10, 0x08, 0x20, 0x00, + 0x80, 0x00, 0x00, 0x30, 0x10, 0x08, 0x20, 0x00, 0x80, 0x00, 0x00, 0x30, + 0x10, 0x0c, 0x10, 0x00, 0x80, 0xf8, 0x03, 0xfc, 0x10, 0xfe, 0x0f, 0x00, + 0x80, 0xf8, 0x03, 0xfc, 0x10, 0x0c, 0x00, 0x00, 0x80, 0x00, 0x00, 0x30, + 0x10, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x30, 0x10, 0x08, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; + +#define up_width 7 +#define up_height 7 +static unsigned char up_bits[] = { + 0x00, 0x08, 0x14, 0x22, 0x41, 0x00, 0x00 }; + +#define down_width 7 +#define down_height 7 +static unsigned char down_bits[] = { + 0x00, 0x41, 0x22, 0x14, 0x08, 0x00, 0x00 }; + +unsigned char len = 0; +unsigned char buf[8]; +bool CANtimeout = false; bool CANtimeout_blink = false; +unsigned long previousMillis = 0; +unsigned long currentMillis = 0; +//char str[20]; +int lcd_categeory = 0; +int lcd_screen = 0; +int lcd_zahl, lcd_comma; +int c100_charger_cell_voltage = 0; +int c101_charger_cell_current = 0; +int c102_charger_cell_power = 0; +int c103_charger_battery_voltage = 0; +int c104_charger_battery_current = 0; +int c105_charger_cell_peakpower = 0; +int c106_charger_work_today = 0; +int c107_charger_work_yesterday = 0; +int c108_charger_work_total = 0; +int c109_charger_co2 = 0; +bool c10a_charger_error = 0; + + +void lcd_format_int(int a){ + lcd_zahl = a/10; + lcd_comma = a%10; +} +void lcd_category_0() { + lcd.setFont(u8g2_font_6x10_tr); + lcd.drawStr(2,7,"PV-Module"); + lcd.drawLine(0, 8, 128, 8); + lcd.drawLine(100, 0, 100, 8); + lcd.drawXBM(106,0, down_width, down_height, down_bits); + lcd.drawXBM(116,0, up_width, up_height, up_bits); +} + +void lcd_print() { + //Print LCD Variables + if (CANtimeout == true && CANtimeout_blink == true) { + lcd.firstPage(); + do { + lcd.setFont(u8g2_font_10x20_tr); + lcd.drawStr(0,20,"CAN Test"); + lcd.drawStr(48,35,"Project"); + lcd.setFont(u8g2_font_6x10_tr); + lcd.drawStr(0,60,"CAN: NO DATA received"); + CANtimeout_blink = false; + } while ( lcd.nextPage() ); + } + else if (CANtimeout == true && CANtimeout_blink == false) { + //CAN Timeout - Error + lcd.firstPage(); + do { + lcd.setFont(u8g2_font_10x20_tr); + lcd.drawStr(0,20,"CAN Test"); + lcd.drawStr(48,35,"Project"); + lcd.drawBox(0, 50, 126, 14); + lcd.setColorIndex(0); + lcd.setFont(u8g2_font_6x10_tr); + lcd.drawStr(0,60,"CAN: NO DATA received"); + lcd.setColorIndex(1); + CANtimeout_blink = true; + } while ( lcd.nextPage() ); + } + if (CANtimeout == false && lcd_categeory == 0 && lcd_screen == 0) { + //Solarzellen + lcd.firstPage(); + do { + lcd_category_0(); + lcd.drawXBM(0,9, Solarpanel_width, Solarpanel_height, Solarpanel_bits); + //lcd_format_int(wert1); + lcd.setCursor(80,18); lcd.print(lcd_zahl); lcd.print("."); lcd.print(lcd_comma); lcd.print("V"); + //lcd_format_int(wert2); + lcd.setCursor(80,28); lcd.print(lcd_zahl); lcd.print("."); lcd.print(lcd_comma); lcd.print("W"); + } while ( lcd.nextPage() ); + } +} + +Task t1(1000, TASK_FOREVER, &lcd_print); + +void setup() +{ + #ifdef debug + Serial.begin(115200); + Serial.println("CAN Test Project - Display Unit"); + delay(1000); + Serial.println("Init MCP2515 CAN Controller..."); + #endif + +START_INIT: + + if(CAN_OK == CAN.begin(CAN_SPEED)) + { + #ifdef debug + Serial.println("Sucessfully initialized."); + #endif + } + else + { + #ifdef debug + Serial.println("Initialization failed, try again."); + #endif + delay(100); + goto START_INIT; + } + #ifdef debug + Serial.println("Init lcd..."); + #endif + lcd.begin(); + lcd.firstPage(); + do { + lcd.setFont(u8g2_font_10x20_tr); + lcd.drawStr(0,20,"CAN Test"); + lcd.drawStr(48,35,"Project"); + lcd.setFont(u8g2_font_6x10_tr); + lcd.drawStr(0,52,"by Carsten Schmiemann"); + lcd.drawStr(30,60,"2021, for Kaubi"); + } while ( lcd.nextPage() ); + delay(2000); + //lcd.clear(); + #ifdef debug + Serial.println("Init threads..."); + #endif + task.init(); + task.addTask(t1); + t1.enable(); +} + +void loop() +{ + task.execute(); + currentMillis = millis(); + //Read CAN Messages + if(CAN_MSGAVAIL == CAN.checkReceive()) + { + CAN.readMsgBuf(&len, buf); + int canid = CAN.getCanId(); + + #ifdef debug + Serial.print("CAN packet received with ID "); Serial.println(canid); + #endif + + currentMillis = millis(); + previousMillis = currentMillis; //Reset Timeout Counter + CANtimeout = false; //Reset Timeout Counter + + switch (canid) + { + case 1: + //wert1 = buf[0] + (buf[1] << 8); + #ifdef debug + Serial.print("Known CAN-ID: "); Serial.print(canid); Serial.print(", Value: "); //Serial.println(wert1); + #endif + break; + + case 2: + //wert2 = buf[0] + (buf[1] << 8); + #ifdef debug + Serial.print("Known CAN-ID: "); Serial.print(canid); Serial.print(", Value: "); //Serial.println(wert2); + #endif + break; + } + } + if (currentMillis - previousMillis > 8000) { + CANtimeout = true; + } +} diff --git a/src/sender.cpp_ b/src/sender.cpp_ new file mode 100644 index 0000000..682441b --- /dev/null +++ b/src/sender.cpp_ @@ -0,0 +1,63 @@ +#include +#include "mcp_can.h" + +#define debug +#define CAN_CS_PIN 49 +#define CAN_SPEED CAN_500KBPS + +unsigned char Flag_Recv = 0; +unsigned char len = 0; +unsigned char buf[8]; +char str[20]; + +MCP_CAN CAN(CAN_CS_PIN); + + +void setup() +{ + #ifdef debug + Serial.begin(115200); + Serial.println("CAN Test Project - Sending Unit"); + delay(1000); + Serial.println("Init MCP2515 CAN Controller..."); + #endif + +START_INIT: + + if(CAN_OK == CAN.begin(CAN_SPEED)) + { + #ifdef debug + Serial.println("Sucessfully initialized."); + #endif + } + else + { + #ifdef debug + Serial.println("Initialization failed, try again."); + #endif + delay(100); + goto START_INIT; + } +} + +void SendIntCAN(int canid, int value) +{ + byte buf[2]; + buf[0] = value & 0x00FF; + buf[1] = (value & 0xFF00) >> 8; + + CAN.sendMsgBuf(canid, 0, 2, buf); +} + +int counter = 0, counter2 = 32767; + +void loop() +{ + counter++; + SendIntCAN(1,counter); + delay(100); + counter2--; + SendIntCAN(2,counter2); + delay(500); +} + diff --git a/test/README b/test/README new file mode 100644 index 0000000..b94d089 --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Unit Testing and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html