Go Down

Topic: Doubts (Read 3619 times) previous topic - next topic

edgar1421


Hello,

Can you increase the speed of the digitalWrite of the arduino due?

On the other hand, how can I know the speed/frequency to which digitalWrite is writing?

And the speed/frequency at which the analogRead reads?


Is it possible to know in the Serial Monitor or is it necessary other tools such as the oscilloscope?


Thanks.

westfw

It is possible to speed it up.
A scope is helpful.
See https://github.com/arduino/ArduinoCore-sam/issues/16
 doesn't seem to have actually made it into the code yet.

ard_newbie


Forget digitalWrite() and use PIO_SODR/PIO_CODR/PIO_ODSR.

Search in the DUE sub forum for example sketches to program these registers.

edgar1421

Thanks.


I have used it PIO_SODR / PIO_CODR / PIO_ODSR where I send the string through the serial monitor.

101010101010101010101010101101010101010101010101010101010101010101010101010.

And I get a final time of 750ms.

Code:

Code: [Select]
int led = 9;
int delT = 10;


String val;
int len;
boolean Send;

void setup() {
  pinMode(led,OUTPUT);
  PIOC->PIO_OWER |= 0x1<<27;
  Serial.begin(9600);
}

void loop() {
    while(Serial.available()){
      val =  Serial.readStringUntil('\n'); 
      delay(1);
    }
 
    if(val!=""){
      //Binary
      Serial.println(val);
      len = val.length();
      Send = true;
    }
 
    if(Send){
      unsigned long time=0;
      time = millis();
     for(int i=0;i<len; i++){
        if(i!=len-1){
          if(val.charAt(i)=='0'){
            REG_PIOC_CODR = 0x1 << 21;
            delay(delT);
          }
          else if(val.charAt(i)=='1'){
            REG_PIOC_SODR = 0x1 << 21;
            delay(delT);
          }
        }
        else{
          //Led off finish
          if(val.charAt(i)=='0'){
            REG_PIOC_CODR = 0x1 << 21;
            delay(delT);
          }
          else if(val.charAt(i)=='1'){
            REG_PIOC_SODR = 0x1 << 21;
            delay(delT);
            REG_PIOC_CODR = 0x1 << 21;
        }
      }
    }
    Serial.print("TIME");
    Serial.println(millis() - time);
    //Reset
    val="";
    Send=false;
  }
}



But using digitalWrite I get the same final time 750ms.

Code:

Code: [Select]
int led = 9;
int delT = 10;


String val;
int len;
boolean Send;

void setup() {
  pinMode(led,OUTPUT);
  Serial.begin(9600);
}

void loop() {
    while(Serial.available()){
      val =  Serial.readStringUntil('\n'); 
      delay(1);
    }
 
    if(val!=""){
      //Binary
      Serial.println(val);
      len = val.length();
      Send = true;
    }
 
    if(Send){
      unsigned long time=0;
      time = millis();
     for(int i=0;i<len; i++){
        if(i!=len-1){
          if(val.charAt(i)=='0'){
            digitalWrite(led,LOW);
            delay(delT);
          }
          else if(val.charAt(i)=='1'){
            digitalWrite(led,HIGH);
            delay(delT);
          }
        }
        else{
          //Led off finish
          if(val.charAt(i)=='0'){
            digitalWrite(led,LOW);
            delay(delT);
          }
          else if(val.charAt(i)=='1'){
            digitalWrite(led,HIGH);
            delay(delT);
            digitalWrite(led,LOW);
        }
      }
    }
    Serial.print("TIME");
    Serial.println(millis() - time);
    //Reset
    val="";
    Send=false;
  }
}




because I get the same time, should not it be faster using PIO_SODR / PIO_CODR / PIO_ODSR ?

ard_newbie

You don't measure the toggle time with your sketch.


Run this sketch:

Code: [Select]

void setup() {
  Serial.begin(250000);
  pinMode(LED_BUILTIN, OUTPUT);

}

void loop() {

  uint32_t Oldmicros;
  Oldmicros = micros();
  for (int i = 0; i < 100000; i++)
  {
    PIOB->PIO_SODR |= PIO_SODR_P27;
    PIOB->PIO_CODR |= PIO_CODR_P27;
  }
  Oldmicros = micros() - Oldmicros;
  printf(" us elapsed for 100000 toggles = %d\n", Oldmicros);
  delay(1000);

  Oldmicros = micros();
  for (int i = 0; i < 100000; i++)
  {
    digitalWrite(LED_BUILTIN, HIGH);
    digitalWrite(LED_BUILTIN, LOW);
  }
  Oldmicros = micros() - Oldmicros;
  printf(" us elapsed for 100000 digitalWrite toggles = %d\n", Oldmicros);
}



edgar1421

Thanks.

Yes, the toggle time it is less.

But one question, in my codes there is a difference if I use digitalWrite to PIO_SODR / PIO_CODR, I mean I get more speed?

westfw

Quote
Code: [Select]
          if(val.charAt(i)=='0'){
In addition to memory fragmentation issues, "Strings" are not "high performance."
You can probably expect  val=""; to take significantly longer than digitalWrite(), for example (it calls free() on the old string!)
If you want this to go fast, you really need to figure out how to use C character arrays (and perhaps even pointers) in the speed-critical sections.



Go Up