[Python / C] J'ai créé un appareil qui fait défiler sans fil l'écran d'un PC à distance.

Synopsis

Lorsque je pratique la bande dessinée avec des amis, j'affiche les lignes sur l'ordinateur devant moi et je l'utilise comme compétition. Si vous affichez les caractères en grande taille, vous ne pouvez pas voir toutes les lignes sans défilement. Par conséquent, j'ai créé un appareil capable de faire défiler à distance l'écran d'un ordinateur personnel de haut en bas.

Configuration du système

J'ai pensé à un système où le PC défile lorsque vous appuyez sur l'interrupteur attaché au contrôleur à portée de main.

La configuration de l'ensemble du système est la suivante.

キャプチャ.PNG

Les détails de l'aperçu du système ci-dessus sont indiqués ci-dessous. (Parce qu'il n'est pas seulement pratique mais aussi destiné à être réalisé dans le cadre d'une étude, je l'ai choisi avec l'intention d'utiliser divers appareils.)

  1. Expéditeur --Microcomputer: ATtiny2313
  1. Côté réception --Microcomputer: Arduino Micro
  1. Côté PC

Après cela, je n'y reviendrai pas dans cet article, mais j'ai utilisé ce qui suit comme outil de débogage de communication tel que la transmission et la réception série.

--Convertisseur USB / série: MR-USBSIR-F

De plus, le module sans fil de Bluetooth a le côté émission (SBDBT) comme esclave et le côté réception (rn42xvp-i / rm) comme maître. La raison en est que SBDBT est un esclave par défaut et qu'un enregistreur d'écriture pour le micro-ordinateur (PIC24FJ64GB004-I / PT) est nécessaire pour passer en maître. D'autre part, étant donné que le paramètre de rn42xvp-i / rm peut être modifié simplement en envoyant une commande à partir d'un terminal tel que le moniteur série Arduino ou TeraTerm, le paramètre de rn42xvp-i / rm du côté de l'envoi a été modifié et utilisé comme maître. (Les détails du réglage seront décrits plus tard)

Je pensais ... mais rn42xvp-i / rm semblait être le maître par défaut. Cependant, même si vous y pensez sans cela, vous pouvez facilement modifier les paramètres et c'est pratique, j'ai donc utilisé rn42xvp-i / rm comme maître.

Réception du module sans fil: paramètres rn42xvp-i / rm

Comme mentionné ci-dessus, les paramètres du module sans fil du côté de la transmission ne peuvent pas être modifiés sans un graveur d'image, donc rn42xvp-i / rm du côté de la réception a été utilisé comme maître. En modifiant à l'avance le réglage de rn42xvp-i / rm en envoyant une commande depuis le terminal, il est possible de connecter des modules Bluetooth entre eux.

La procédure est illustrée ci-dessous. Vous pouvez le faire à partir du moniteur série d'Arduino IDE ou de TeraTerm. Lors de l'exécution à partir du moniteur série d'Arduino, exécutez après avoir écrit ce qui suit.

change_bt_settings.c


#include <SoftwareSerial.h>

#define BT_RX 8
#define BT_TX 7
#define BPS 115200 // rn42xvp-i/vitesse de transmission par défaut de rm

SoftwareSerial btSerial(BT_RX, BT_TX); //Paramètres série pour interagir avec Bluetooth

void setup()
{
  Serial.begin(BPS); // PC -Initialisation de la communication série entre Arduino
  btSerial.begin(BPS); // Arduino -Initialisation de la communication série entre Bluetooth
}

void loop()
{
  //Processus de transmission d'Arduino vers Bluetooth
  if (Serial.available())
  {
    btSerial.print(char(Serial.read()));
//    btSerial.write(Serial.read()); //OK aussi ici]
  }

  //Traitement de réception du signal de Bluetooth
  if (btSerial.available())
  {
    Serial.print(char(btSerial.read()));
//    Serial.write(btSerial.read()); //OK aussi ici
  }
  delay(50);
}

De plus, j'ai renvoyé à l'article suivant pour sa mise en œuvre. ・ Http://workpiles.com/2014/04/rn42-bluetooth1/ ・ Htp: // Kosakai. Rld. Kokan. jp / R-42. html

La procédure de réglage est la suivante.

nombre commander nouvelle ligne réponse sens
1 $$$ Aucun CMD Démarrer le mode de commande
2 SA,0 Oui AOK Modifié pas besoin de s'authentifier pour la connexion
3 SU,96 Oui AOK Changer la vitesse de transmission à 9600
4 R,1 Oui Reboot! Redémarrez le module (cela reflétera les changements de paramètres)

Ce que j'ai fait (matériel)

    1. Expéditeur (ATtiny2313)

J'ai pensé à quoi utiliser comme base, mais des assiettes en plastique ordinaires et des assiettes universelles Comme il est difficile à traiter, nous avons utilisé une plaque de styrène expansé de 5 mm d'épaisseur, relativement rigide et facile à traiter. Le panneau de styrène expansé a été traité à une taille appropriée, et un boîtier de batterie et un panneau ont été fixés.

image.png

image.png

  1. Côté réception (Arduino Micro)

Le côté récepteur peut être directement connecté à un ordinateur personnel, je l'ai donc créé avec une maquette.

image.png

fichier source

    1. Expéditeur (ATtiny2313)

send_data_to_arduino.c


#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
 
#define OFF 0   //Pour la commutation
#define ON  1   //Comme ci-dessus
#define READ  0 //Pour le réglage du registre de port
#define WRITE 1 //Comme ci-dessus
#define CNTD  0 //Utilisé pour mesurer le temps pendant lequel l'interrupteur est maintenu enfoncé
#define CNTU  1 //Comme ci-dessus
#define KRTIME 100000 //Il est temps de maintenir le commutateur enfoncé pour être reconnu comme poussé


void AVR_init(void)
{
	//Paramètres tels que la communication série
	DDRD=(READ<<PD0)|(WRITE<<PD1)|(READ<<PD4)|(READ<<PD5)|(WRITE<<PD6);
}

void USART_init(void)
{
	unsigned int baud;
	baud=8000000/16/9600-1;          //Calcul de la vitesse de transmission(La formule de calcul est la spécification P.75 Répertorié en bas)
	UBRRH=(unsigned char)(baud>>8);  //Réglage de la vitesse de transmission(Octet supérieur)
	UBRRL=(unsigned char)baud;       //Réglage de la vitesse de transmission(Octet inférieur)
	UCSRC=(0<<USBS)|(3<<UCSZ0);      //Définissez la longueur de bit utilisée sur 8 bits et le bit d'arrêt sur 2 bits
	UCSRB=(1<<RXEN)|(1<<TXEN);       //Envoyer / recevoir l'autorisation
}

void Utx(char *data) //Transmission de données
{
	int i;
	
	//Caractère de terminaison "\Boucle à "0"
	for(i=0; data[i]!='\0'; i++)
	{
		while(!(UCSRA & (1<<UDRE)) );
		UDR=data[i];
	}
}

void INT_init(void)
{
	//INT0 et 1(Broches 6 et 7)Autoriser les interruptions
	GIMSK=0b11000000; //Registre de validation d'interruption générale
	MCUCR=0b00001111; //Réglez le déclenchement d'interruption externe sur le front montant pour INT0 et 1
// 	SREG=0b10000000;  //Interruption multiple désactivée → Désactivée par défaut
}

ISR(INT0_vect) //Gestionnaire d'interruption de la broche 7
{
	//Mesures de bavardage
	_delay_ms(50);
	EIFR=ON<<INTF0;

	Utx("UP");
	Utx("_");  //Caractère de terminaison
}

ISR(INT1_vect) //Gestionnaire d'interruption de la broche 6
{
	//Mesures de bavardage
	_delay_ms(50);
 	EIFR = ON<<INTF1;

	Utx("DOWN");
	Utx("_");  //Caractère de terminaison
}

unsigned char Urx(void) //Réception de données
{
	while(!(UCSRA & (1<<RXC)) );
	return UDR;
}

int main(void)
{
	//Répétition des touches(Maintenez l'interrupteur enfoncé)Mesure du temps
	static unsigned long rptcnt[1] = {}; //Puisque int est devenu 2 octets, déclarez-le aussi longtemps
	
	AVR_init();
	USART_init();
	INT_init();
	sei(); //Toutes les instructions d'autorisation d'interruption
		
	PORTD=ON<<PD6; //Sortie toujours 5V(Pour la commutation)

	for(;;)
	{
		//Traitement de la correspondance pour maintenir le bouton enfoncé
		if (bit_is_set(PIND, 4)) //Lorsque PD4 est 1 (en appuyant sur le bouton)
		{
			if (rptcnt[CNTD] > KRTIME) //Détecte le maintien
			{
				Utx("UP");
				Utx("_"); //Caractère de terminaison
				_delay_ms(100);
			}
			else //Ajouter le temps de répétition des touches
			{
				rptcnt[CNTD]++;
			}
		}
		else if (bit_is_set(PIND, 5)) //Lorsque PD5 est 1 (en appuyant sur le bouton)
		{			
			if (rptcnt[CNTU] > KRTIME) //Détecte le maintien
			{
				Utx("DOWN");
				Utx("_"); //Caractère de terminaison
				_delay_ms(100);
			}
			else //Ajouter un temps d'attente
			{
				rptcnt[CNTU]++;
			}
		}
		else //Effacer le temps de maintien à zéro
		{
			rptcnt[CNTD] = 0;
			rptcnt[CNTU] = 0;
			// memset(rptcnt, 0, sizeof(rptcnt)*10); //Ne pas utiliser car cela dépend du système de traitement
		}
	}
}
  1. Côté réception (Arduino Micro)

relay_data_to_PC.c


#include <SoftwareSerial.h>

#define BT_RX    8 // Arudino-Utilisé pour la communication série entre Bluetooth
#define BT_TX    7 //Comme ci-dessus
#define BAUD  9600 //Vitesse de transmission pour la communication série
#define OUT_5V   2 //Code PIN
#define IN_5V    3 //Comme ci-dessus
#define LED_OUT  4 //Comme ci-dessus
#define BUFF_MAX 5 //Capacité du tampon de réception série (unité: caractères)

// Arudino-Paramètres série du logiciel entre Bluetooth
SoftwareSerial btSerial(BT_RX, BT_TX);

void setup()
{
  Serial.begin(BAUD);
  btSerial.begin(BAUD);
  pinMode(OUT_5V, OUTPUT); //Utilisé pour la commutation
  pinMode(IN_5V,  INPUT);  //Comme ci-dessus
}

void init_bt() //Connexion avec le module Bluetooth
{
  btSerial.print("$$$"); //Transition vers le mode réglage
  delay(1000);
  btSerial.print("C,00198600035E\n"); //Connectez-vous à d'autres modules Bluetooth
  delay(5000);
  btSerial.print("---\n"); //Quitter le mode commande si la connexion échoue (ignoré en cas de succès)
}

void loop()
{
  char buff[BUFF_MAX]={'\0'};
  static int cnt = 0;
  
  digitalWrite(OUT_5V, HIGH); //Sortie toujours 5V (pour la commutation)

  //Connexion Bluetooth après avoir appuyé sur le commutateur
  if (digitalRead(IN_5V))
  {
    init_bt();
  }

  //Processus de transmission vers le module Bluetooth (utilisé lors de la transmission depuis un moniteur série)
  if (Serial.available())
  {
    btSerial.print(char(Serial.read()));
    delay(100);
  }

  //Recevoir le traitement du module Bluetooth
  if (btSerial.available())
  {
    //Envoyer la valeur reçue côté PC
    Serial.print(btSerial.readStringUntil('_')); //Utilisez Until car readString est lent (l'argument est un caractère terminal)
    delay(100);
  }
}
    1. Côté PC (seulement c'est Python)

scroll_screen_bt.py



import serial
import re
import pyautogui as pgui


def ctrl_screen():  # 0.Effectuer le traitement à des intervalles de 08sec
    with serial.Serial('COM8', 9600, timeout=0.08, stopbits=serial.STOPBITS_TWO) as ser:

        while True:
            val = ser.readline()
            val = val.decode() #Convertir le type d'octets en type str (chaîne de caractères unicode)

            if val == 'UP':
                pgui.typewrite(['up'])  #Faites défiler l'écran
            elif val == 'DOWN':
                pgui.typewrite(['down'])  #Faites défiler l'écran


if __name__ == "__main__":

    ctrl_screen()

circuit

Le schéma de circuit de ce système est illustré ci-dessous. J'ai utilisé draw.io pour dessiner. J'ai écrit un schéma de circuit pour la première fois, mais c'est gratuit, facile à écrire et pratique!

    1. Expéditeur (ATtiny2313)

image.png

  1. Côté réception (Arduino Micro)

image.png

Comment utiliser

    1. Côté PC, lancez le script Python.
  1. Allumez le maître et l'esclave. (Le maître se connecte uniquement au PC)

    1. Appuyez sur l'interrupteur du côté maître pour connecter les modules Bluetooth. Si la connexion réussit, la LED clignotante sera allumée. Prêt maintenant image.png
  2. Appuyez sur l'interrupteur du côté esclave pour faire défiler l'écran du PC de haut en bas. image.png

Précautions de mise en œuvre

Si vous modifiez le réglage d'ATtiny2313 pour utiliser un oscillateur à cristal externe, bien sûr, si vous ne connectez pas d'oscillateur à cristal externe, le micro-ordinateur ne fonctionnera pas ou n'écrira même pas. Un oscillateur interne suffit! Si vous le réglez pour utiliser un oscillateur externe sans oscillateur externe, vous ne pourrez rien faire à moins de connecter un oscillateur externe (je suis).

En outre, lors de l'utilisation de la bibliothèque série logicielle avec Arduino, il existe des restrictions sur les broches pouvant être utilisées. Détails ci-dessous ↓ https://garretlab.web.fc2.com/arduino_reference/libraries/standard_libraries/SoftwareSerial/

Informations qui ont servi de référence

En plus des sites mentionnés jusqu'ici dans cet article, les sites suivants ont été endettés. Merci beaucoup.

Contenu Lier la destination
Utilisation de base d'ATtiny2313 http://lumenbolk.com/?p=19
Solution pour l'erreur causée par "importation série" https://teratail.com/questions/101843
PC(Python)Communication série entre et Ardino https://qiita.com/Acqua_Alta/items/9f19afddc6db1e4d4286
Kbhit dans Arduino()Convivialité de https://forum.arduino.cc/index.php?topic=294636.0
Comment détecter les événements clés dans Arduino https://www.quora.com/How-do-I-detect-a-keyboard-event-in-an-Arduino-IDE-program
Méthode d'opération de clé par Python https://www.lisz-works.com/entry/pyautogui-key
Méthode de fonctionnement des touches par Arduino https://garretlab.web.fc2.com/arduino_reference/language/functions/usb/keyboard/write.html
Comment recevoir des chaînes de caractères dans la communication série Arduino https://ch.nicovideo.jp/yugata/blomaga/ar1177727

finalement

Il vaut mieux faire ça ici ... ou quelque chose qui cloche ici! Si vous avez des questions, désolé de vous déranger, mais si vous pouvez le signaler, je serai heureux de verser des larmes.

Recommended Posts

[Python / C] J'ai créé un appareil qui fait défiler sans fil l'écran d'un PC à distance.
J'ai fait un bot mou qui m'informe de la température
J'ai fait un calendrier qui met à jour automatiquement le calendrier de distribution de Vtuber
J'ai fait un programme pour vérifier la taille d'un fichier avec Python
J'ai créé une fonction pour voir le mouvement d'un tableau à deux dimensions (Python)
J'ai fait un script pour enregistrer la fenêtre active en utilisant win32gui de Python
[Python] J'ai créé un code de scraping web qui acquiert automatiquement le titre de l'actualité et l'URL de Nihon Keizai Shimbun.
[Python] Un programme qui compte le nombre de vallées
J'ai créé une VM qui exécute OpenCV pour Python
Points Python du point de vue d'un programmeur en langage C
Un mémo que j'ai touché au magasin de données avec python
[Python] Un programme qui compare les positions des kangourous.
J'ai créé une application Twitter qui décrypte les caractères de pré-connexion avec heroku (échec)
J'ai fait un calendrier qui met à jour automatiquement le calendrier de distribution de Vtuber (édition Google Calendar)
J'ai fait un texte Python
J'ai fait une fonction pour vérifier le modèle de DCGAN
J'ai fait une image ponctuelle de l'image d'Irasutoya. (partie 1)
J'ai fait une image ponctuelle de l'image d'Irasutoya. (partie 2)
Script Python qui compare le contenu de deux répertoires
[Atcoder] [C ++] J'ai fait un outil d'automatisation de test qui peut être utilisé pendant le concours
J'ai créé une fonction pour découper l'image de python openCV, alors veuillez l'utiliser.
J'ai créé un programme en Python qui change les données de 1 minute de FX en une heure arbitraire (1 heure, etc.)
J'ai créé un site d'apprentissage C ++
J'ai fait un package qui peut comparer des analyseurs morphologiques avec Python
J'ai fait un Line-bot avec Python!
J'ai créé un robot Line qui devine le sexe et l'âge d'une personne à partir de l'image
[Introduction à Python] J'ai comparé les conventions de nommage de C # et Python.
J'ai fait une loterie avec Python.
Une fonction qui mesure le temps de traitement d'une méthode en python
J'ai fait un shuffle qui peut être réinitialisé (inversé) avec Python
J'ai essayé de créer un outil d'échafaudage pour le framework Web Python Bottle
J'ai créé un démon avec Python
J'ai fait un programme qui calcule automatiquement le zodiaque avec tkinter
[python] Une note que j'ai commencé à comprendre le comportement de matplotlib.pyplot
L'histoire de la création d'un module qui ignore le courrier avec python
[python] J'ai créé une classe qui peut écrire rapidement une arborescence de fichiers
[Python] Un programme qui fait pivoter le contenu de la liste vers la gauche
[Kaggle] J'ai fait une collection de problèmes en utilisant le didacticiel Titanic
[Python] J'ai analysé le journal d'un homme au cours de sa première année de vie professionnelle et j'ai fait un jugement positif / négatif sur la vie professionnelle.
[Python] J'ai créé un robot qui me dit la température actuelle lorsque j'entre un nom de lieu sur LINE
[Python] Un programme qui calcule le nombre de segments de chocolat qui remplissent les conditions
[Explication AtCoder] Contrôlez les problèmes A, B, C d'ABC182 avec Python!
[Python] J'ai fait un décorateur qui ne semble pas avoir d'utilité.
J'ai créé une application Web en Python qui convertit Markdown en HTML
[Python] Un programme qui calcule le nombre de chaussettes jumelées
J'ai créé un bot Discord en Python qui se traduit quand il réagit
[Python] J'ai créé un utilitaire qui peut accéder au type dict comme un chemin
J'ai créé un konoha de bibliothèque qui fait passer le tokenizer à une belle sensation
J'ai créé un outil qui facilite un peu la décompression avec CLI (Python3)
[IOS] J'ai créé un widget qui affiche la tendance de Qiita dans Pythonista3. [Python]
J'ai fait une erreur en récupérant la hiérarchie avec MultiIndex of pandas
Python: je souhaite mesurer proprement le temps de traitement d'une fonction
[Explication AtCoder] Contrôle ABC184 Problèmes A, B, C avec Python!
[Python] Note: Fonction auto-conçue pour trouver la zone de distribution normale