Arduino Inline ASM With Strings

For a project for school, we have to use inline assembly in our project somewhere. My plan was to compare the value from a sensor and change what the display words will be depending on if the value is above a certain range. I am using a SparkFun Redboard Qwiic which is attached to a Soil Moisture sensor but my main issue is with the asm in this part.
Here is my code:

void setup() {
  
  Serial.begin(9600);
  
  uint8_t value = 3;
  char display_words[19] = "                  ";
  const char wet[19] = "Wet,  Do Not Water";
  const char dry[17] = "Dry, Water Me :(";
  
 
  asm (
    "cp 5, %[value0] \n\t"
    "brge _high \n\t"
    "jmp _end \n\t"
    
    "_high:               \n"
    "ld   __tmp_reg__, Z+ \n"  //load tmp reg w/src char
    "st   X+, __tmp_reg__ \n" //store tmp reg to dst 
    "tst  __tmp_reg__     \n" //check if 0 (end)
    "brne _high           \n"

    "_end: \n\t"
    "ld   __tmp_reg__, Y+ \n"  //load tmp reg w/src char
    "st   X+, __tmp_reg__ \n" //store tmp reg to dst 
    "tst  __tmp_reg__     \n" //check if 0 (end)
    "brne _end           \n"
    
    : :  "x" (display_words), [value0] "r" (value), "z" (wet), "y" (dry)
  );
  Serial.print("Test: "); 
  Serial.println(display_words);
  
}

void loop() {
 
}

This was a simple test in a new sketch that would eventually make it to the full code which all works except for this part.

I am stuck after looking up many resources. If anyone could help that would be greatly appreciated!

No, that's a picture of your code.
Please read this post and consider editing your post accordingly:

im sorry im new :frowning:

Not derogatory. Just some guidelines that will help everyone help you better.
Awesome job fixing your post.

Both loops execute. I suspect that's not what you want. I also suspect that will overrun display_words.

1 Like

I am getting an error saying "can't find a register in class 'POINTER_Y_REGS' while reloading 'asm'" and i fixed the fact that both loops run anyway thank you.

If you'd like more help you will have to post the updated version.

void setup() {
  Serial.begin(9600);
  
  uint8_t val = 3;
  char display_words[18] = "Wet, Do Not Water";
  const char dry[18] = "Dry, Water Me :( ";
 
  asm (
    "cpi %2, 5 \n"
    "brlt 2f\n"
    
    "1: ld __tmp_reg__, Z+ \n"
    "st X+, __tmp_reg__ \n" 
    "tst __tmp_reg__ \n"
    "brne 1b \n"
    "2: \n"

    : :  "x" (display_words), "z" (dry), "r" (val)
  );

  Serial.print("Test: "); 
  Serial.println(display_words);
}

void loop() { }
1 Like

Thank you so much! This worked like a charm!

Hi! Sorry for the late reply but I was wondering how difficult it would be to add 1 more string and comparison for an intermediate string to be displayed in the middle such that lower than 3 displays the dry string, between 3 and 6 displays a new middle string, and lastly above 7 will display the wet string?

Let me know how I did on my homework.

char s1[18] = "Dry, Water Me :( ";
char s2[18] = "New middle string";
char s3[18] = "Wet, Do Not Water";

// lower than 3 displays the dry string,
// between 3 and 5 displays a new middle string,
// and lastly above 7 will display the wet string?
char* test(uint8_t val)
{
  asm volatile (
    "cpi %0, 3 \n"
    "brlo 1f \n"
  
    "cpi %0, 8 \n"
    "brsh 2f \n"
  
    "ldi r24, lo8(s2) \n"
    "ldi r25, hi8(s2) \n"
    "rjmp 3f \n"
  
    "1: ldi r24, lo8(s1) \n"
    "ldi r25, hi8(s1) \n"
    "rjmp 3f \n"
  
    "2: ldi r24, lo8(s3) \n"
    "ldi r25, hi8(s3) \n"
    
    "3: \n"
    :  : "r" (val), "e" (s1), "e" (s2), "e" (s3)
  );
}

void setup() {
  Serial.begin(9600);
  Serial.println(test(1));
  Serial.println(test(4));
  Serial.println(test(8));
}

void loop() { }

note: per your instructions, what should happen when val = 6?

i meant 3-6 it was a typo, my bad! thank you for the response!

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