Site icon AranaCorp

Adicionar a função F() a um ficheiro .INO com Python

Um dos grandes interesses da programação é automatizar tarefas simples. Um bom exemplo que encontrei foi a modificação de várias linhas de código num ficheiro INO para o Arduino.

Depois de escrever algumas dezenas de linhas de código em C++ para o meu projeto Arduino, dei por mim com um problema de memória que não conseguia resolver. Ao fazer alguma pesquisa, deparei-me com a função F(), que permite que cadeias de caracteres sejam colocadas na memória Flash. Isto poupa muito espaço quando Serial.print() é muito utilizado. Em vez de modificar o código à mão, escrevi um script python para inserir a função F() em Serial.print().

Descrição do método

Em primeiro lugar, é necessário abrir o ficheiro de destino antes de efetuar qualquer operação e, em seguida, não esquecer de o fechar quando terminarmos de o utilizar.

fileb=open( destfile, "w" )
fileb.close()

Em seguida, temos de percorrer o ficheiro original linha a linha.

with open(filename) as inofile:
    for line in inofile:
        print(line)

Quando for possível navegar no ficheiro, detectamos a presença de “Serial.print” e “Serial.println” em cada linha. Para o fazer, criamos uma função que devolve uma lista das posições destas cadeias de caracteres em cada linha.

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

Para cada linha, se as cadeias de caracteres “Serial.print” e “Serial.println” não forem detectadas, escrevemos a linha no novo ficheiro tal como está.

if len(indexln)==0 and len(indexl)==0:
			fileb.write(line)

Caso contrário, modificamos primeiro as cadeias de caracteres “Serial.println” e depois as cadeias de caracteres “Serial.print”. Em cada caso, verificamos se a função F não está já presente. Se estiver, deixamos a linha inalterada e copiamo-la de volta para o ficheiro de destino.

if newl.find('F("')>0:
					pass

Caso contrário, detectamos a posição dos parênteses e das aspas e recuperamos a cadeia de caracteres

j=newl.find('("')
k=newl.find('")')
newlk=newl[j+1:k+1]

Finalmente, substituímos a cadeia recuperada pela mesma cadeia inserida na função F.

print("change String to F()-> "+'Serial.println(F('+newlk+'))')
line=line.replace(newlk,'F('+newlk+')')

Antes de escrever a linha modificada no ficheiro de destino.

fileb.write(line)

Aqui está um bom exemplo de como usar um script Python para simplificar a sua vida. Não hesites em dizer-nos nos comentários se este tutorial foi útil para ti ou se encontras alguma coisa em falta, errada ou que precise de ser melhorada.

Código completo

Aqui está o código completo que pode copiar para testar. Tudo o que precisa de fazer é alterar os endereços do ficheiro de origem (filename) e do ficheiro de destino (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()

Possíveis melhorias

Fontes

Exit mobile version