0

I am currently trying to connect my Arduino Uno to my computer and let them communicate via UART. I started using a project from Github (here), which I'm trying to modify to get the next step via UART. Because of that, I'm not able to switch programming languages and also need to override the bootloader.

However, I can't get the serial connection to work.

#include "Joystick.h"
#include <avr/io.h>
#include <util/delay.h>
#include <Arduino.h>

These are the #include statements at the top, but <Arduino.h> can't be found...

If I remove these statements, Serial can't be found (from the main-Method: Serial.begin(9600);)

It's my first time to program with C, did I overlook a stupid mistake? Thanks for any help...

  • 1
    Are you using the Arduino IDE to compile this? – chrisl Dec 28 '19 at 14:27
  • @chrisl No, I'm using the makefile that is contained in the GitHub project. I modify the $PATH variable every time to contain arduinoInstallDir/hardware/tools/avr/bin, which includes the avr-gcc needed for it to compile. – MonsterDruide1 Dec 28 '19 at 14:39
  • You can very easily combine C and C++ code. Just compile your parts of the code as C++, and include the existing C functions you need as extern "C". If you need to call your C++ function from C code, declare it extern "C" as well. You can then use all of the C++ features from the Arduino core if you want. – tttapa Dec 28 '19 at 15:51
  • @tttapa I've tried my best to work out how that works, but I can't get it. I found examples for how to include one method, but not for an entire library. Is also thought about converting that whole project to C++, but that also won't work as I don't fully understand it. If you could give me an example on how to include a full library like <Arduino.h> in a C file and make it still usable, I would be really thankful. – MonsterDruide1 Dec 29 '19 at 15:22
  • I started to look into it, but it seems to me that the code is intended to run on the ATmega16U2 of the UNO, not the ATmeg328P. In that case, I don't think there's an Arduino Core available for that chip, so you would have to program the USB CDC stack yourself (should be possible using LUFA, but I don't have the time to look into it). And IMHO, it's absolutely not worth any more time. I'd use a microcontroller that supports USB natively, and has decent software support, like a Teensy 3.x. – tttapa Dec 29 '19 at 15:46
0

I would consider using HoodLoader2 instead of that LUFA project. If you can't do that, you can compile parts of the Arduino Core together with the LUFA project.

The main steps:

  • Add the necessary Arduino source files to the SRC variable in the Makefile.
  • Add the Arduino core folder to the include path by appending to the CC_FLAGS and CXX_FLAGS variables.
  • Move the main function to a new main.cpp file and add it to the Makefile SRC as well.
  • Include the Joystick.h file in your main file in an extern "C" block.
  • Include the HardwareSerial.h file in your main file as well.

My files after these changes:

Makefile

# Set the MCU accordingly to your device (e.g. at90usb1286 for a Teensy 2.0++, or atmega16u2 for an Arduino UNO R3)
MCU          = atmega16u2
ARCH         = AVR8
F_CPU        = 16000000
F_USB        = $(F_CPU)
OPTIMIZATION = s
TARGET       = Joystick
SRC          = $(TARGET).c Descriptors.c main.cpp $(LUFA_SRC_USB)
LUFA_PATH    = ./lufa/LUFA
CC_FLAGS     = -DUSE_LUFA_CONFIG_HEADER -IConfig/
LD_FLAGS     =


ARDUINO_PATH = ${HOME}/.arduino15/packages/arduino/hardware/avr/1.8.1/cores/arduino
SRC         += $(ARDUINO_PATH)/HardwareSerial.cpp
SRC         += $(ARDUINO_PATH)/HardwareSerial1.cpp
SRC         += $(ARDUINO_PATH)/Print.cpp
CXX_FLAGS   += -I$(ARDUINO_PATH) -I./HoodLoader2/avr/variants/HoodLoader2
CC_FLAGS    += -I$(ARDUINO_PATH) -I./HoodLoader2/avr/variants/HoodLoader2

...

main.cpp

extern "C" {
#include "Joystick.h"
}

#include <HardwareSerial.h>

// Main entry point.
int main(void) {
    // We'll start by performing hardware and peripheral setup.
    SetupHardware();
    // We'll then enable global interrupts for our use.
    GlobalInterruptEnable();
    // Initialize the UART
    Serial1.begin(115200);
    Serial1.println(F("Hello, world"));
    // Once that's done, we'll enter an infinite loop.
    for (;;)
    {
        // We need to run our task to process and deliver data for our IN and OUT endpoints.
        HID_Task();
        // We also need to run the main USB management task.
        USB_USBTask();
    }
}

Joystick.c
Deleted the main function.

To get it to compile after these changes:

# (inside of the snowball-thrower folder)
git submodule add https://github.com/NicoHood/HoodLoader2.git HoodLoader2
make

This compiles without problems for me, but I have no idea if it actually works.

Edit:

You'll notice that the program uses more RAM than the ATmeg16U2 has available. You could solve this by moving the step array to PROGMEM, or by shrinking the Serial buffers.

avr-size --mcu=atmega16u2 --format=avr Joystick.elf
AVR Memory Usage
----------------
Device: atmega16u2

Program:    5076 bytes (31.0% Full)
(.text + .data + .bootloader)

Data:        527 bytes (102.9% Full)
(.data + .bss + .noinit)

 [INFO]    : Finished building project "Joystick".
  • I've tried that, but I can't confirm that the program really started. I've connected an UART-to-USB-Bridge and tested it before, but PuTTY doesn't output the starting test entry. Instead, the last thing that was programmed with Arduino gets executed and outputted to PuTTY... I've got around the RAM-Issue by just deleting the last part of the step-array, because I'm trying to completely avoid that by streaming the entries via UART. However, neither the starting output gets displayed nor the switch notices a new controller connected. – MonsterDruide1 Dec 30 '19 at 19:14
  • I need to correct myself: It get's noticed from the switch if I disconnect TX&RX while flashing the new .hex file. But still no output from PuTTY (and yes, I reconnect TX & RX after finished flashing the image). The connection/interaction with the switch is the same as before, so that is perfectly fine, but the Serial-Connection still does not work. – MonsterDruide1 Dec 30 '19 at 19:26
  • @MonsterDruide1 Upload an empty sketch to the ATmega328P first (using the original '16U2 Arduino firmware), or connect its reset pin to ground. And also swap your RX/TX pins. The RX of the UART-to-USB adapter should be connected to the RX pin of the Arduino (this is the TX pin of the '16U2), and TX to TX. Internally, the RX/TX pins are connected like this (ignore the ESP8266, imagine that it's the UART-to-USB adapter). – tttapa Dec 30 '19 at 19:38
  • 1
    YES!!!! Thank you VERY much for all of that help. Everything now works as expected! – MonsterDruide1 Dec 30 '19 at 20:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.