I am Confused wether I can use pinMode() and digitalRead() in C Code

I just bought an Arduino Pro Micro (atmega32u4) and a ELEGOO Unu R3 starter kit so I'm admittedly very new to writing code for arduino. I had used the IDE for configuring and Compiling Marlin for my 3D printers but this is my first personal project.

I am trying to add buttons to this code that I know was converted to C at some point based on the comments if you follow the forks back far enough. The Base code takes reverse engineered Controller code to Create a Switch compatible button library for macros.

At first I thought I could use

#define buttonOne 6
bool buttonOneState;
pinMode(buttonOne, INPUT_PULLUP);

with

buttonOneState = digitalRead(buttonOne);

In the loop I wanted it to check but this fails to compile saying

src/wildareabreeding.c:149:9: note: in expansion of macro 'buttonOne'
 pinMode(buttonOne, INPUT_PULLUP);
         ^
src/wildareabreeding.c:149:20: error: unknown type name 'INPUT_PULLUP'
 pinMode(buttonOne, INPUT_PULLUP);

I have been compiling through Git Bash with this line as instructed from the original code

C:\Users\Dracrius\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude -CC:\Users\Dracrius\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf -v -patmega32u4 -cavr109 -PCOM7 -b57600 -D -Uflash:w:D:\pkmn-swsh-automation-tools-master\pkmn-swsh-automation-tools\wildareabreeding.hex:i

Maybe I'm missing a reference but deep down I thought it was because the code is in C and those only work in the IDE but then after some research the IDE is using C so maybe I'm missing something really small because the only other thing I've been able to find is one fork of this code does have buttons but they use bit operators and directly reference things which seems miles over my head. I understand most of it but idk how to find all the refrences for my arduino and the bits to pin matchup. Also I can't for the life of me find out how you use the internal Pullup resistors with that method. The page refrencing it here mentions you can do it in code but not how to do it!

This is what the other method from the other fork looks like. I have no idea what the whole commented out part is about and I can't tell if they are using the internal pullup resistors. The githubs instructions and wiring diagram make no mention of resistors (not even for the led so that spikes concern). The source is here!

uint8_t PushButton_D0(void) {
 //return 1; !(uint8_t)(PINB & _BV(PB6));
 //static uint8_t btn = _BV(PB6);
 //uint8_t t = PINB;  // read port status
 DDRD &= ~(1<<PD0);
 PORTD |= (1<<PD0);
 if (! (PIND & (1<<PD0))){
 return 0;
 } else {
 return 1;
 }
 }

And Finally I will link to the modifications I tried to make in full on Pastbin
Thank you in advanced any help or guidance is much appreciated!

When you compile a sketch inside the IDE, it automatically includes Arduino.h (among other things) and I believe that is where INPUT_PULLUP is defined.

#define INPUT_PULLUP 0x2

I thought it was because the code is in C and those only work in the IDE but then after some research the IDE is using C

An Arduino sketch is basically written in C, but the build process includes a bunch of Arduino-specific libraries that define things like pinMode() and digitalRead() (automatically and basically invisibly to the programmer.)
In this case, the program you have is designed to compile in "plain" avr-c, so it has some things like PORTD defined, but it does NOT have access to the Arduino functions.
Keeping track of which functions come from where is one of the banes of a programmer's existence :frowning:

blh64:
When you compile a sketch inside the IDE, it automatically includes Arduino.h (among other things) and I believe that is where INPUT_PULLUP is defined.

#define INPUT_PULLUP 0x2

If it is that simple amazing would I need to copy Arduino.h into my project or can I just reference it with an

#include "Arduino.h"

westfw:
An Arduino sketch is basically written in C, but the build process includes a bunch of Arduino-specific libraries that define things like pinMode() and digitalRead() (automatically and basically invisibly to the programmer.)
In this case, the program you have is designed to compile in "plain" avr-c, so it has some things like PORTD defined, but it does NOT have access to the Arduino functions.
Keeping track of which functions come from where is one of the banes of a programmer's existence :frowning:

Haha I hear that and partly expected this may be the cause. Can I simply add references to these libraries to make use of them, or would I also have to include them in the project folder I compile from?

Is there a convenient list of which libraries are needed for Arduino functions?

@Dracrius, it's still not clear to me what you're trying to do. Do you want to compile a project clearly not intended for the Arduino environment / tool chain in that environment? Or, do you want to attempt to implement functionality from the Arduino environment into another environment / tool chain? IMO, either one of those tasks seems to be a recipe for making your life difficult.

Have you been able to get the original, unmodified, project to compile using the documented tool chain? If so, congratulations. I've read the instructions at the GitHub you linked several times and I still can't figure out how to do it. But, to be honest, I can't even figure out what the project is.

Regardless, if you've gotten that far, then I'd advise continuing that way. I'd next load the project on to a Teensy++ 2.0 -- because the documentation says it was tested on that platform. If that works, then you're ready to modify it to add your buttons. Grab the Atmel Datasheet for the Processor and learn how to configure and read/write the Port I/O pins using the PORTx, DDRx, and PINx registers (Chapter 10). This Link will be helpful. Also, learn a little bit about bitwise operations in the C language ('|', '&', '>>', '<<', '^'). After that, configuring the pins and reading button inputs will be straightforward.

The above may sound daunting. But, I really think it will be easier in the end than what you're trying to do.

gfvalvo:
@Dracrius, it's still not clear to me what you're trying to do. Do you want to compile a project clearly not intended for the Arduino environment / tool chain in that environment? Or, do you want to attempt to implement functionality from the Arduino environment into another environment / tool chain? IMO, either one of those tasks seems to be a recipe for making your life difficult.

Have you been able to get the original, unmodified, project to compile using the documented tool chain? If so, congratulations. I've read the instructions at the GitHub you linked several times and I still can't figure out how to do it. But, to be honest, I can't even figure out what the project is.

Regardless, if you've gotten that far, then I'd advise continuing that way. I'd next load the project on to a Teensy++ 2.0 -- because the documentation says it was tested on that platform. If that works, then you're ready to modify it to add your buttons. Grab the Atmel Datasheet for the Processor and learn how to configure and read/write the Port I/O pins using the PORTx, DDRx, and PINx registers (Chapter 10). This Link will be helpful. Also, learn a little bit about bitwise operations in the C language ('|', '&', '>>', '<<', '^'). After that, configuring the pins and reading button inputs will be straightforward.

The above may sound daunting. But, I really think it will be easier in the end than what you're trying to do.

To be clear I already have the base code compiling and running on an atmega32u4. The actual base fork was made for an Uno R3 and was tested on Arduino Micro(atmega32u4) as well. This fork I am starting from and a few forks do use a Teensy but its really not required. I'm not surprised you can't follow their install instructions either as they are pretty bad and it took me a few days just to get past that. But you do it from Git bash using make and then the line I dropped was what you use to install it on the arduino.

I also apologize I forgot the fork I'm using is kind of the least respectful of the bunch in that everyone else links old forks in their descriptions cause they all made very minimal changes. The best starting point is this "Switch-Fightstick" which is actually a Splatoon 2 "printer" which is the original fork of "Switch-Fightstick" which is a "Proof-of-Concept Fightstick for the Nintendo Switch. Using the LUFA library and reverse-engineering of the Pokken Tournament Pro Pad for the Wii U to enable custom fightsticks on the Switch System v3.0.0"

I am trying to implement functionality from the Arduino environment. Or actually to be completely honest as the entire question suggest I'm actually inquiring if that is even possible because if it is and if it is as easy as westfw and blh64 imply it really shouldn't be a nightmare they are just c functions nothing that special I just dont know how to add said functions properly. As in, what do I need to add to #include the files to my project. Sounds like possible just Arduino.h and pins_arduino.h maybe the other files each includes as its not hard to check with a find #include.

But if that isn't possible or is unfeasible I was looking for clarification on the use of the internal pullup resistor with PORTx, DDRx, and PINx registers because even the page you link to says clear as day it is easier and more advised to use pinMode() and digitalread. It actually doesn't even say in any way that that would only work in Arduino IDE and so how to work outside of the ide to do the same thing!

This is the stem of my problem this documentation and the post I linked are the most helpful information I could find and I can decipher 90% of how to do it in this way especially with the code from the last fork using this method BUT said fork is concerning in his lack of mentioning or using ANY resistors so without 100% understanding this method I can not tell if they have used the internal Pullup resistors for these button and even the doc you linked has no explanation of how to use the internal pullup resistors with the registry methods.

Really this is the only reason I didn't just use the registry but secondly I would much rather keep my final build more accessible and if I go defining specific pin registries the code becomes locked to this single board. Since many of the people I'd like to share this with are not proficient in this sort of thing and seeing as it even held me up I really don't want that. I'd like to be able to publish it like the other forks with the option to use at least the uno, micro and tennsys!

Dracrius:
The best starting point is this "Switch-Fightstick" which is actually a Splatoon 2 "printer" which is the original fork of "Switch-Fightstick" which is a "Proof-of-Concept Fightstick for the Nintendo Switch. Using the LUFA library and reverse-engineering of the Pokken Tournament Pro Pad for the Wii U to enable custom fightsticks on the Switch System v3.0.0"

I assume that all means something to you. It means nothing to me, apparently some sort of video game thingy. Regardless, it's not germane to the issue at hand.

Or actually to be completely honest as the entire question suggest I'm actually inquiring if that is even possible because if it is and if it is as easy as westfw and blh64 imply it really shouldn't be a nightmare they are just c functions nothing that special I just dont know how to add said functions properly. As in, what do I need to add to #include the files to my project. Sounds like possible just Arduino.h and pins_arduino.h maybe the other files each includes as its not hard to check with a find #include.

If you really want to try going that route, all I can tell you is give it a go and see if it works. I imagine you may end up in a frustrating hunt for a seemingly endless list of #include files. Also, remember that many #include files are specific to certain processors and boards. The Arduino IDE sorts all that out when you select the board type.

But if that isn't possible or is unfeasible I was looking for clarification on the use of the internal pullup resistor with PORTx, DDRx, and PINx registers because even the page you link to says clear as day it is easier and more advised to use pinMode() and digitalread. It actually doesn't even say in any way that that would only work in Arduino IDE and so how to work outside of the ide to do the same thing!

It's all covered in Chapter 10 of the processor's datasheet. That's why I provided you a link to that document. Although, now that I understand you're not compiling for Teensy++2.0, you'll have to use the datasheet for the 32U4 or ATMega328P (Uno). No matter, the technique is identical for all AVR processors. Only the specific port-to-pin assignments change.

AFAICT, the OP has some code that implements a video game controller on a 32u4 board, and they want to modify the code to support additional buttons.
The original code is written in pure C, but they have familiarity with the Arduino IDE/"language", and would like to use Arduino Functions to make the modifications.

Not unreasonable.

But non-trivial to actually make work. While in theory you can link Arduino libraries, doing so will tend to result in a cascade of additional requirements. For example, pinMode and digitalRead both require the table used to translate Arduino pin numbers into AVR port/bitmask combinations.

The effort of making that work is probably comparable to just implementing your own functions like "pullup6on()" and "readpin6()" using "direct port manipulations", except that there is probably more documentation and tutorial info on direct port IO than there is on re-factoring the Arduino libraries.

Agreed. But, I think the re-factoring will be even more work than just configuring and reading the ports/pins using "non-Arduino" techniques.

Ok fair enough I'm happy to learn my way through direct port manipulations and I apologize gfvalvo for my "explanation" I was try to clarify what it did and after rereading it I guess I could understand that still was a bit specific of an explanation.

I like the idea of making my own functions as westfw suggests but I'm more then a little rusty it'll take me a good afternoon to think of and write the logic for that haha

In the mean time any pointers on making my final code/functions easily modified for the three boards in question (ATMega32u4,ATMega328P and AT90USB1286) for a lay man user who can basically just follow a readme? My end goal was to make something very user friendly and tweaking pin registries seems quite the opposite.

The effort of making that work is probably comparable to just implementing your own functions like "pullup6on()" and "readpin6()" using "direct port manipulations", except that there is probably more documentation and tutorial info on direct port IO than there is on re-factoring the Arduino libraries.

Thank you so very much btw I'm almost 100% certain the phrases "direct port manipulations" and "direct port IO" will greatly improve my searches for instructions on how to work with IO in C. I always meant to learn my way around C anyways so I'm in no means married to Arduino IDE it was just hard to find the wording with no knowledge of the subject. I really think I included 'Arduino' in most of my searches for using the internal pull-up resistors in C and that probably didn't help things as I'm now realizing that's far to specific.

Also thank you gfvalvo I do see the for mentioned parts in Chapter 10 I seem to have read your post poorly originally and thought it was supposed to be in the Arduino page you linked. It may have been because I focused on that it was for the Teensy but knowing I can find the same chapter for the ATMega32u4 will help me find it. I'm also hoping I can find a few videos lectures to really wrap my head around it so I'm a little less worried I'm gonna fry something making my own functions.

To answer the original question: you can certainly use pinMode() and digitalWrite() in C code:
sketch.ino:

extern "C"
{
  void SetLEDPinmode(int mode);
  void SetLEDPin(boolean b);
}


void setup()
{
  SetLEDPinmode(OUTPUT);
}


void loop()
{
  SetLEDPin(HIGH);
  delay(250);
  SetLEDPin(LOW);
  delay(250);
}

Functions.c:

#include <Arduino.h>


void SetLEDPinmode(int mode)
{
  pinMode(LED_BUILTIN, mode);
}


void SetLEDPin(boolean state)
{
  digitalWrite(LED_BUILTIN, state);
}

you can certainly use pinMode() and digitalWrite() in C code

You can use them from within C code in an Arduino "sketch"/project with no problems.

The Question is whether and/or how to use them from withing a pure "C project", that doesn't have access to "Arduino.h", doesn't use setup()/loop(), and doesn't know where wiring_digital.c is.
(Hmm. wiring_digital.c is where the arduino code for pinMode() and digitalRead() and etc lives. I don't know if it will be helpful for you to look at, but it IS worthwhile to remember that all of the Arduino software is Open Source, so you can always "just look at it.")

westfw:
The Question is whether and/or how to use them from withing a pure "C project", that doesn't have access to "Arduino.h", doesn't use setup()/loop(), and doesn't know where wiring_digital.c is.

Why would a 'C' program not have access to Arduino.h? Just include it like any other library include. Name the appropriate folders in your Make file. You may have to specify some defines that are provided by the IDE.

Yes, you can use Arduino.h in a pure C app.

Sketch.ino:/* This File Has No Contents */

Functions.c:

#include <Arduino.h>

int main()
{
  init();  // Initialize the Arduino run-time

  pinMode(LED_BUILTIN, OUTPUT);
  
  while (true)
  {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(500);
    digitalWrite(LED_BUILTIN, LOW);
    delay(500);
  }
  return 0;
}

Why would a 'C' program not have access to Arduino.h? Just include it like any other library include.

Also add wiring_digital.c. And variant.h and variant.cpp (be sure to get the right ones!) And figure our which of the many compile switches normally given to the compiler by the IDE are actually relevant and non-damaging to the non-Arduino program.
And... I'm not sure what else, but I'll stick by my statement that it's probably easier to figure out direct port manipulation.