How to change register values from a PC without relying on the arduino processor completely

I'm looking for a way to control registers and pins on a microcontroller (such as an Arduino) using Python or C++ without relying entirely on the Arduino itself. My goal is to be able to write more complex code without being limited by the capacity or limitations of the Arduino.

Does anyone know or have experience on how to do this? For example, is there a way to communicate directly with the microcontroller using a low programming protocol (such as JTAG, SWD, or ISP) via a computer, and control the registers and GPIO pins without having to manually upload firmware to the Arduino each time?

I want to avoid the memory or capacity limitations of the Arduino and focus more on developing more flexible and complex code. I really appreciate if anyone can provide guidance or references related to this.

Thank you!

what about commands sent via the serial monitor to configure and control the state of pins?

// pcRead - debugging using serial monitor

const char version [] = "PcRead 240209a";

int debug = 0;

// -----------------------------------------------------------------------------
// process single character commands from the PC
#define MAX_CHAR  10
char s [MAX_CHAR] = {};

int  analogPin = 0;

void
pcRead (void)
{

    static int  val = 0;

    if (Serial.available()) {
        int c = Serial.read ();

        switch (c)  {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            val = c - '0' + (10 * val);
            break;

        case 'A':
            analogPin = val;
            Serial.print   ("analogPin = ");
            Serial.println (val);
            val = 0;
            break;

        case 'D':
            debug ^= 1;
            break;

        case 'I':
            pinMode (val, INPUT);
            Serial.print   ("pinMode ");
            Serial.print   (val);
            Serial.println (" INPUT");
            val = 0;
            break;

        case 'O':
            pinMode (val, OUTPUT);
            Serial.print   ("pinMode ");
            Serial.print   (val);
            Serial.println (" OUTPUT");
            val = 0;
            break;

        case 'P':
            pinMode (val, INPUT_PULLUP);
            Serial.print   ("pinMode ");
            Serial.print   (val);
            Serial.println (" INPUT_PULLUP");
            val = 0;
            break;


        case 'a':
            Serial.print   ("analogRead: ");
            Serial.println (analogRead (val));
            val = 0;
            break;

        case 'c':
            digitalWrite (val, LOW);
            Serial.print   ("digitalWrite: LOW  ");
            Serial.println (val);
            val = 0;
            break;

        case 'p':
#if !defined(ARDUINO_ARCH_ESP32)
            analogWrite (analogPin, val);
            Serial.print   ("analogWrite: pin ");
            Serial.print   (analogPin);
            Serial.print   (", ");
            Serial.println (val);
            val = 0;
#endif
            break;

        case 'r':
            Serial.print   ("digitalRead: pin ");
            Serial.print   (val);
            Serial.print   (", ");
            Serial.println (digitalRead (val));
            val = 0;
            break;

        case 's':
            digitalWrite (val, HIGH);
            Serial.print   ("digitalWrite: HIGH ");
            Serial.println (val);
            val = 0;
            break;

        case 't':
            Serial.print   ("pinToggle ");
            Serial.println (val);
            digitalWrite (val, ! digitalRead (val));
            val = 0;
            break;

        case 'v':
            Serial.print ("\nversion: ");
            Serial.println (version);
            break;

        case '\n':          // ignore
            break;

        case '?':
            Serial.println ("\npcRead:\n");
            Serial.println ("    [0-9] append to #");
            Serial.println ("  # A - set analog pin #");
            Serial.println ("  # D - set debug to #");
            Serial.println ("  # I - set pin # to INPUT");
            Serial.println ("  # O - set pin # to OUTPUT");
            Serial.println ("  # P - set pin # to INPUT_PULLUP");
            Serial.println ("  # a - analogRead (pin #)");
            Serial.println ("  # c - digitalWrite (pin #, LOW)");
            Serial.println ("  # p - analogWrite (analogPin, #)");
            Serial.println ("  # r - digitalRead (pin #)");
            Serial.println ("  # s  - digitalWrite (pin #, HIGH)");
            Serial.println ("    t  - toggle pin output");
            Serial.println ("    v  - print version");
            Serial.println ("    ?  - list of commands");
            break;

        default:
            Serial.print ("unknown char ");
            Serial.println (c,HEX);
            break;
        }
    }
}

// -----------------------------------------------------------------------------
void
loop (void)
{
    pcRead ();
}

// -----------------------------------------------------------------------------
void
setup (void)
{
    Serial.begin(9600);

    Serial.println (version);
#if defined(ARDUINO_ARCH_ESP32)
    Serial.println ("esp32");
#endif
}
1 Like

I don't know, it might be like Firmata but it can control the registers completely, I don't know if a library like the one I want exists.

wish you would better explain what you're hoping to do, what doesn't my suggested do?

what does

mean?

do you want to actually having complicated code running on a PC and just using the Arduino as a hardware interface?

Yes, that's right, so if there is a big change in the system there is no need to update the Arduino Frimware many times, just change the application version, I hope you understand what I mean.

i believe the code i posted does that. did you ulook at it?

i wrote it to configure, read and write pins without having to change and re-program the Arduino.

perhaps you want something more standard like Firmata, but it seems to do the same thing with more text

Several arduinos have chips that implement debug protocols that would theoretically permit writing “registers” from a pc based debug environment. Swd and updi, for instance.

Firmatta is at a somewhat higher level, permitting the pc to essentially execute “arduino code” (like digitalRead()) and return results, using code on the arduino to help.

Either is going to be much slower than native code on the arduino.

Some will let you run an interactive python interpreter on the arduino and send python code…

Seems an odd way to go abou things. The point of a arduino is to run code independently of the pc, and the limitations are just something you have to deal with.

2 Likes

I think you’re overestimating your coding capabilities, or underestimating the abilities of microcontrollers.

1 Like

You should write a very detailed description what you want to do and what the most final purpose of such a control is.

Where is the substantial difference between a pretty special program using JTAG to change register-values inside the microcontroller and compile and flashing a new firmware?

Some more questions:
Do you plan to only switch on off IO-pins at a maximum fequency of 10 Hz.?
or
Do you plan to use hardware based pwm which makes a big difference to simple IO-pin switching.

At the moment with that less info to me even using a remote-computer to access some other computer remotely to compile / flash new code seems to be easier to realise than developping a firmware that is able to enable / disable all the special things like hardware-timers, hardware-counters, interrupts etc.

1 Like

Use a Due or an ESP32 or one of the more modern incarnations of Arduino.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.