One of the big interests of programming is to automate simple tasks. A good example I have encountered is the modification of several lines of code in an INO file for Arduino.
After writing a few dozen lines of code in C++ for my Arduino project, I found myself with a memory problem that I couldn’t solve. When I asked around, I came across the F() function which allows you to place strings in Flash memory. This saves a lot of space when using a lot of Serial.print(). Rather than changing the code by hand, I wrote a python script to insert the F() function into the Serial.print().
Description of the method
First of all we must open the destination file before carrying out operations on it and then remember to close it when we have finished using it.
fileb=open( destfile, "w" )
fileb.close()
Then we have to go through the original file line by line.
with open(filename) as inofile:
for line in inofile:
print(line)
Once it is possible to browse the file, we detect the presence of “Serial.print” and “Serial.println” on each line. To do this, we create a function that will return a list of the positions of these strings on each line.
def find_all_indexes(input_str, search_str): l1 = [] length = len(input_str) index = 0 while index < length: i = input_str.find(search_str, index) if i == -1: return l1 l1.append(i) index = i + 1 return l1
For each line, if the strings “Serial.print” and “Serial.println” are not detected, we write the line to the new file as is.
if len(indexln)==0 and len(indexl)==0:
fileb.write(line)
Otherwise, we will first modify the “Serial.println” channels and then the “Serial.print” channels. In each case, we check that the F function is not already present. In this case, we do not modify the line and copy it in the destination file.
if newl.find('F("')>0:
pass
Otherwise, we detect the position of brackets and inverted commas and retrieve the character string
j=newl.find('("')
k=newl.find('")')
newlk=newl[j+1:k+1]
Finally, we replace the recovered character string by the same string inserted in the F function.
print("change String to F()-> "+'Serial.println(F('+newlk+'))')
line=line.replace(newlk,'F('+newlk+')')
Before writing the modified line to the destination file.
fileb.write(line)
Here’s a good example of how to apply a Python script to simplify your life. Feel free to comment if this tutorial has been useful to you or if you find things missing that are wrong or need improvement.
Full code
Here is the complete code that you can copy to test. All you have to do is modify the addresses of the original file (filename) and the destination file (destfile).
#!/usr/bin/python3.4 # -*-coding:Utf-8 -* def find_all_indexes(input_str, search_str): l1 = [] length = len(input_str) index = 0 while index < length: i = input_str.find(search_str, index) if i == -1: return l1 l1.append(i) index = i + 1 return l1 filename=".\Grab_Parts\Grab_Parts.ino" destfile=".\Grab_Partsb.ino" fileb=open( destfile, "w" ) with open(filename) as inofile: #data = file.read() for line in inofile: #print(line) #print(line.find("Serial.println")) indexln=find_all_indexes(line,"Serial.println") indexl=find_all_indexes(line,"Serial.print(") if len(indexln)==0 and len(indexl)==0: fileb.write(line) else: #change Serial.println for i in indexln: print("---------------------------------------------------") newl=line[i:] print(newl) if newl.find('F("')>0: pass else: j=newl.find('("') k=newl.find('")') newlk=newl[j+1:k+1] print(newlk) if( newlk.find('"')==0): print("change String to F()-> "+'Serial.println(F('+newlk+'))') line=line.replace(newlk,'F('+newlk+')') #print("Result ==> "+line) #fileb.write(line) #change Serial.print after indexl=find_all_indexes(line,"Serial.print(") for i in indexl: print("---------------------------------------------------") newl=line[i:] print(newl) if newl.find('F("')>0: pass else: j=newl.find('("') k=newl.find('")') newlk=newl[j+1:k+1] print(newlk) if( newlk.find('"')==0): print("change String to F()-> "+'Serial.print(F('+newlk+'))') #fileb.write('Serial.println(F('+newlk+'))') line=line.replace(newlk,'F('+newlk+')') print("Result ==> "+line) fileb.write(line) #print(indexl) fileb.close()
Possible improvements
- Automatic detection of INO files in a directory tree to modify all the files in the same folder.