Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Adding digitalToggle to core?

Abierto
#130 6 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
35/100
Tipo de issue
Nueva funcionalidad
Claridad
Bastante claro
Estado de actividad
Estancado
Stack tecnológico
cpp
Área
embedded-iot

Línea de trabajo

Empieza leyendo la declaración propuesta en Arduino.h y la implementación AVR en wiring_digital.c; después, revisa ArduinoCore-API issue 77 y los issues y el pull request de Arduino enlazados. El trabajo estará terminado cuando se haya decidido la forma de la API, incluido el valor de retorno, y se haya determinado si la propuesta es adecuada más allá de la implementación AVR mostrada.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

enhancement
Description

The Arduino core has a digitalWrite() and a digitalRead() function.
In many sketches there is a need to toggle a pin, either for a blinking LED or a clock pin for swSPI etc.

There are two typical ways to invert a pin - see code below

  // using a state holding the value of the pin
  digitalWrite(pin, state);
  state = 1 - state;

  // read pin, invert and write back
  digitalWrite(pin, !digitalRead(pin));

The latter one is slower as it redo a lot of "pin math", so I implemented a version of digitalToggle() for AVR.
Attached test sketch shows the gain compared to the two methods.

Results test on UNO
Time us		1000 calls
Reference:	7392	// read invert write
      Var:	4784	// use state var
   Toggle:	3964	// use digitalToggle returning state
   Toggle:	3520	// use digitalToggle returning NO state

The gain of toggle returning state is 46% resp 16%
The gain of toggle returning NO state is 52% resp 26%

Imho these gains are interesting, esp for clocking data

Implementation for AVR

Arduino.h

uint8_t digitalToggle(uint8_t pin);     // returns the new state of the pin

wiring_digital.c

uint8_t digitalToggle(uint8_t pin)
{
  uint8_t port = digitalPinToPort(pin);
  volatile uint8_t *out;

  if (port == NOT_A_PIN) return 0;
  uint8_t timer = digitalPinToTimer(pin);
  if (timer != NOT_ON_TIMER) turnOffPWM(timer);

  uint8_t bit = digitalPinToBitMask(pin);

  out = portOutputRegister(port);
  uint8_t oldSREG = SREG;
  cli();
  *out ^= bit;      // invert bit
  SREG = oldSREG;
  return ((*out & bit) != 0);
}

Note: a no state returning version is straightforward given the above code.

Test sketch

digitalToggle.zip

uint32_t start, Tref, Tref2, Tnew;
const uint8_t pin = 13;

uint8_t state = LOW;

void setup()
{
  Serial.begin(115200);
  Serial.println();
  Serial.println(__FILE__);

  pinMode(pin, OUTPUT);
  digitalWrite(pin, LOW);

  start = micros();
  for (int i = 0; i < 1000; i++) digitalWrite(pin, !digitalRead(pin));
  Tref = micros() - start;

  start = micros();
  for (int i = 0; i < 1000; i++)
  {
    digitalWrite(pin, state);
    state = 1 - state;
  }
  Tref2 = micros() - start;

  start = micros();
  for (int i = 0; i < 1000; i++) digitalToggle(pin);
  Tnew = micros() - start;

  Serial.print("Reference:\t");
  Serial.println(Tref);
  Serial.print("      Var:\t");
  Serial.println(Tref2);
  Serial.print("   Toggle:\t");
  Serial.println(Tnew);
  Serial.print("     Gain:\t");
  Serial.println(Tref - Tnew);
  Serial.print("     Perc:\t");
  Serial.println(100.0 - (100.0 * Tnew) / Tref, 1);

  pinMode(13, OUTPUT);
}

void loop()
{
  static int cnt = 0;
  if (cnt == 60)
  {
    cnt = 0;
    Serial.println();
  }
  cnt++;
  // digitalToggle(pin);
  int x = digitalToggle(pin);
  Serial.print(x);

  delay(1000);
}
Additional context
Additional requests
Lenguaje dominante
C++
Estrellas
306
Forks
150
Métricas de merge de PR
Sin PR fusionados en 30 d

Preparar el entorno

Aún no hemos revisado los archivos de configuración de este proyecto. Empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de arduino/ArduinoCore-API

Todos los issues de arduino/ArduinoCore-API

Issues similares

Más issues de C++

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.