2024年6月30日日曜日

簡単SG90/DCMドライバTB67H450/MAX98357 /逆起電力保護DIODE

サーボモータの動かし方|キム日記 (kimudiary.com)

サーボの電源とPICのそれは別々にとる!GNDは共通化すること!

これはCCPをつかわん実にイージーな方法だがわかりやすい

PICマイコン(PIC16F1827)でサーボモーターを操作する | スマートライフを目指すエンジニア (smtengkapi.com)   1827 モシニャガ本にないので貴重だが難解

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

モータードライバー(TA7291P)の使い方 [Arduino] (petitmonte.com)

上記はむしろTB1662、L293Dに近い方式でpwmピンが別建て 上記ドライバが入手困難 

よってTB67H450(モノ)をシングルモータドライバでPIC実習 

pwm別建てでない よってDRV8835/8833に近い

ArduinoとモータドライバICによるDCモータの駆動制御 (take26.com) 

RS/gnd,VREF/5v or 3.3v あとはドライバicのgndと

マイコンのそれは共通化しておく ちなみにVMには単3x4が推奨(3x3でも動いたが)

analogwriteはD3/D5/D6/D9/D10/D11(ナノの場合)しかつかえない

このサイトではrefを3.3vにつないでいたが5vでもうごいた

しかもdigitalwriteでもうごいたので PICマイコン実習もこれで成功した

----------------------------------------------------------------------------

 https://www.mikan-tech.net/entry/raspi-i2s-max98357a :: i2s dac decoder and raspi

https://dronebotworkshop.com/esp32-i2s/ :: on esp32

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

https://monoist.itmedia.co.jp/mn/articles/0802/22/news130.html ダーリントン

https://monoist.itmedia.co.jp/mn/articles/0802/27/news137.html FET

cf  https://nagomi0132.hateblo.jp/entry/2022/02/02/150614 トランジスタ保護ダイオード

https://www.nfcorp.co.jp/techinfo/dictionary/036/ これも逆起電力の説明

https://www.youtube.com/watch?v=C0QsaHiXWHM  これも

2024年6月29日土曜日

spi-ram/mccでeuartにstdio.hを/c-mcc(CCPcaptureでUS)


spi-ramの配線は上記を参考にした 

https://ameblo.jp/pi-poh/entry-12667969903.html のプルアップ不要だった

cs,miso,mosi,sck::10,12,11,13のままholdとncをvccにつなぐのがキモだった!

#include <SPI.h>

void setup()
{
  Serial.begin(115200);
  pinMode (SS, OUTPUT);
  digitalWrite(SS,HIGH);

  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV4);
  SPI.setDataMode(SPI_MODE0);
}

void loop()
{
  byte write_data = 0;
  byte read_data = 0;
  word ram_address = 0x0000;

  while(1)    //1=無限ループ
  {
    ram_wr( ram_address , write_data);
    read_data = ram_rd( ram_address );

    Serial.print("ram_address =");
    Serial.print(ram_address);
    Serial.print(" : write_data =");
    Serial.print(write_data);
    Serial.print(" : read_data =");
    Serial.println(read_data);

    ram_address++;
    write_data++;
    delay(500);

  }//while
}

//ライトシーケンス
void ram_wr(word add , byte data)
{
  byte add_H;
  byte add_L;
 
  add_H = highByte(add);  // 上位4ビット(アドレス)
  add_L = lowByte(add);       //  下位4ビット
 
  digitalWrite(SS,LOW);
  SPI.transfer(0x02);          //0x02=書き込みモード
  SPI.transfer(add_H);
  SPI.transfer(add_L);
  SPI.transfer(data);
  digitalWrite(SS,HIGH);
}

//リードシーケンス
int ram_rd( word add )
{
  byte add_H;
  byte add_L;
  byte r_data;
 
  add_H = highByte(add);
  add_L = lowByte(add);
 
  digitalWrite(SS,LOW);
  SPI.transfer(0x03);           //0x03=読み込みモード
  SPI.transfer(add_H);
  SPI.transfer(add_L);


  r_data = SPI.transfer(0);  // この0は多分ダミーデータだろう

  

digitalWrite(SS,HIGH);

 
  return r_data;
}

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

c-mcc book p298 :: pic16f18857でeuratするには

redirect to にチェックをいれるのとc90に変更するのが両方必要だった!

ーーーーーーーーーーーーーーーーーーーーーーーーーーーー

c-mcc book p360 :: pic16f18857 以下に成功

/*****************************************

 *  CCP キャプチャモード例題

 *  超音波距離系のパルス幅測定

 ****************************************/

#include "mcc_generated_files/mcc.h"

#include "lcd8x2_lib.h"

// 変数定義

uint16_t RiseEdge, FallEdge, Line2[10];

double Distance;

/******* メイン関数 *********************/

void main(void){

    SYSTEM_Initialize();

    lcd_init();

    lcd_str("Distance");

    /****** メインループ ***********/

    while (1)

    {


        TMR1_WriteTimer(0);                 // タイマ0リセット

        // トリガ出力

        Trig_SetHigh();

        __delay_us(10);

        Trig_SetLow();

        // 計測実行 1usec単位

        while(!CCP1_IsCapturedDataReady()); // 立ち上がり

// echoピンがhighになると上記のwhileから脱出

            RiseEdge = CCP1_CaptureRead();

        __delay_ms(100);

        while(!CCP1_IsCapturedDataReady()); // 立下り

//  every edgeの設定にて上記同様にechoピンがlowになるとwhileから脱出 多分!

            FallEdge = CCP1_CaptureRead(); 

        // 距離に変換しLCD表示  音速=343m/s 20℃

        Distance = (double)(FallEdge - RiseEdge)*343/20000;

        sprintf(Line2, "%3.1f cm  ", Distance);

        lcd_cmd(0xC0);

        lcd_str(Line2);

        __delay_ms(2000);

    }

}    


2024年6月28日金曜日

NCOをMCCなしで実装 :: PIC16F18313(XREAさんより)

 // http://machoto2.g2.xrea.com/page/P16F18313/P18313_a23.htm

  /* File: NCO sample
  * System ClockはConfigで内部1MHzに設定
  * NCO を RA2 に出力
  * PIC16F18313
  * Created on 2021-12-18
  **************************************/

 #include <xc.h>
 #define _XTAL_FREQ 1000000      // delay_ms(x) のための定義
 #define SW  RA5                 // Push SW

 // 音の高さを決める定数
  const int inc_tbl[] = {
 //    Do,    Re,   Mi,   Fa,   So,   Ra,  Si,   Do
     0x225,0x268,0x2B3,0x2DC,0x336,0x39B,0x40C,0x449
  };

 #pragma config FEXTOSC = OFF,RSTOSC = HFINT1  // HFINTOSC (1MHz)
 #pragma config CLKOUTEN = OFF,CSWEN = OFF,FCMEN = OFF
 #pragma config MCLRE = ON,PWRTE = OFF,WDTE = OFF,LPBOREN = OFF
 #pragma config BOREN = OFF,BORV = LOW,PPS1WAY = OFF,STVREN = ON
 #pragma config DEBUG = OFF
 #pragma config WRT = OFF,LVP = ON,CP = OFF,CPD = OFF

 void main(void) {
     char idx = 0;
     LATA   = 0;
     TRISA  = 0b101011;          // PORTA5を入力に設定 PORTA3::RESET
     ANSELA = 0;                 // 全てのpinをデジタルに設定
     WPUA   = 0b111111;          // PORTA入力に弱プルアップ
// なぜかOPTION_REGの設定が不要

     // NCO 設定 ****************************************
     NCO1CLK = 0b00000001;       // Fosc (1 MHz)がクロック
     RA2PPS  = 29;               // RA2にNCO出力

     while(1){
         NCO1CON = 0b10000000;               // NCO ON FDCモード
         for(char i = 0;i < 8;i++){          // オクターブ(8回)繰り返し
             NCO1INCH = inc_tbl[i] >> 8;     //  音階データをセット
             NCO1INCL = inc_tbl[i] & 0xFF;   //  音階データをセット
             __delay_ms(500);                // 500ms演奏
         }
         NCO1CON = 0;                        // NCO OFF
         while(SW);                          // SWが押されるのを待つ
     }
 }

2024年6月23日日曜日

linux terminal soft

ls /dev/tty*でターミナルをしるのが第一歩

ーーーーーーーーーーーーーーーーーーーーーー

 minicom::

https://qiita.com/baggio/items/3db759da67c0123e993e にくわしい

sudo minicom -sでdflに設定が書き込めた

-----------------------------------------------------

picocom ::

https://wiki.archlinux.jp/index.php/%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB に詳しい


2024年6月15日土曜日

後閑メモ、timer1 gate toggle, aqm0802 (adruino,12f1822)

 サポートページ:改訂新版 8ピンPICマイコンの使い方がよくわかる本:|技術評論社 (gihyo.jp)

cf https://akizukidenshi.com/catalog/g/g113837/ timer1 gate toggle mode 

https://maicommon.ciao.jp/ss/Arduino_g/LCD_I2C/index.htm でうごいた

contrastは0802用に0x20とすべし vddは3.3vですべし

http://jh7ubc.web.fc2.com/pic/PIC12F1822/PIC12F1822_AQM0802A.htmlを参考に

以下のように改変

#include <stdio.h>

#include <stdlib.h>

#include <xc.h>

#include <pic12f1822.h>

// CONFIG1

#pragma config FOSC = INTOSC

#pragma config WDTE = OFF

#pragma config PWRTE = ON

#pragma config MCLRE = OFF

#pragma config CP = OFF

#pragma config CPD = OFF

#pragma config BOREN = ON

#pragma config CLKOUTEN = OFF

#pragma config IESO = OFF

#pragma config FCMEN = OFF

// CONFIG2

#pragma config WRT = OFF

#pragma config PLLEN = ON

#pragma config STVREN = ON

#pragma config BORV = HI

#pragma config LVP = ON // mplab-snap用に必須

#define _XTAL_FREQ 32000000

#define LCD_addr 0x7C  //3E+0

/* I2C 初期化*/

void I2C_init(){

SSP1CON1 = 0x28; //SSPEN = 1,I2C Master Mode

SSP1STATbits.SMP = 1; //標準速度モード(100KHz)

SSP1ADD = 0x4F; //Fosc/(4*Clock)-1 Clock=100kHz,Fosc=32MHz

}


/* スタートコンディション */

void I2C_start(){

SEN = 1;

while(SEN);

}


/* ストップコンディション */

void I2C_stop(){

SSP1IF = 0;

PEN = 1;

while(PEN);

SSP1IF = 0;

}


/* I2Cに1byte送信 */

void I2C_write(unsigned char dat){

SSP1IF = 0;

SSP1BUF = dat;

while(!SSP1IF);

}


/* write command */

void LCD_cmd(unsigned char cmd){

I2C_start(); //start condition

I2C_write(LCD_addr); //send slave address

I2C_write(0x00); //send control byte

I2C_write(cmd); //send command

I2C_stop(); //stop condition

}


/* write charactor */

void LCD_char(unsigned char dat){

//unsigned char ackn; なくても動いたジャンクコード

I2C_start(); //start condition

I2C_write(LCD_addr); //send slave address

I2C_write(0x40); //send control byte

I2C_write(dat); //send data

I2C_stop(); //stop condition

}


/* LCD 初期化 */

void LCD_init(){

__delay_ms(40); //40ms wait

LCD_cmd(0x38); //8bit,2line

LCD_cmd(0x39); //IS=1 : extention mode set

LCD_cmd(0x14); //Internal OSC Frequency

LCD_cmd(0x70); //Contrast set

LCD_cmd(0x56); //Power/ICON/Contrast Control

LCD_cmd(0x6C); //Follower control

__delay_ms(200);//200ms wait

LCD_cmd(0x38); //IS=0 : extention mode cancel

LCD_cmd(0x0C); //Display ON

LCD_cmd(0x01); //Clear Display

__delay_ms(2); //wait more than 1.08ms

}


/* Clear Display */

void LCD_clear(){

LCD_cmd(0x01);

__delay_ms(1);

__delay_us(80);

}


/* Return Home `*/

void LCD_home(){

LCD_cmd(0x02);

__delay_ms(1);

__delay_us(80);

}


/* Cursor 2line top */

void LCD_2line(){

LCD_cmd(0xC0);

}


/* write 1 charactor to LCD */

void putC(unsigned char ch){

LCD_char(ch);

} // 実際には使われないジャンクコードっぽい部分


/* write string */

void putstr(const unsigned char *s){

while(*s){

LCD_char(*s++);

}

}


void main() {

OSCCON = 0b01110000 ; // 内部クロック8MHz

ANSELA = 0b00000000 ; // アナログは使用しない

TRISA = 0b00001110 ; // RA1,RA2,RA3は入力、他は出力

PORTA = 0b00000000 ; // 出力ピンの初期化


I2C_init();

LCD_init();

putstr("JH7UBC");

unsigned char count = 0;

char STR[10]; // 10もいらんかもしれんが。。。

while(1){

LCD_2line();

sprintf(STR, "%3d",count);  // これでcountからputstrに渡す文字列をつくる!

putstr(STR);

count++;

__delay_ms(500);

}

}


2024年6月10日月曜日

OpeAmpについて・モータドライバ・ステッパ

負電源のつくりかた LTC1144でマイナス電圧の生成

https://miha.jugem.cc/?eid=247 

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

https://875s.com/kousaku/ ここは電子工作の宝庫

単電源オペアンプについて学習したのは以下のサイト群

http://zattouka.net/GarageHouse/micon/circuit/OP.htm :: lm358n 

http://zattouka.net/GarageHouse/micon/Arduino/Temp/Temp.htm :: lm61 only

http://zattouka.net/GarageHouse/micon/Arduino/Temp/Temp2.htm::lm61+lm358n

------------------------------------------------------------------------------------------------

https://mag.switch-science.com/2020/05/08/motor-driver/ 

 上記は  TB67H450 (ys got)  TA7291P(no got) の比較記事  

https://www.cqpub.co.jp/hanbai/books/42/42101/42101_10syo.pdf これは後者の記事

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

 6ピンステッパ http://zattouka.net/GarageHouse/micon/Motor/Stepping2.htm

         

2024年6月6日木曜日

2024年6月4日火曜日

pulse generator/nslookup dig install on raspi

https://www.youtube.com/watch?v=wxETzpOzVSQ :: convenient pulsse generator

------------------------------------------------------------------------------

8ピン本で ambient ipが54.65.206.59 ambient である理由をしるため色々しらべた

https://www.miki-ie.com/network/raspi-network-utility-dnsutils/ でラズパイにnslookup/digインスト

nslookup ambidata.io 8.8.8.8 でip情報がでた 8ピン本はこれをつかっとるな

------------------------------------------------------------------------------------------------------

2024年6月2日日曜日

scoppy (pico/androi) portable oscillo for 3v

 https://developer.mamezou-tech.com/blogs/2024/03/18/raspberry-pi-pico-to-oscilloscope/

https://oscilloscope.fhdm.xyz/wiki/firmware-versions :: firmware

https://picockpit.com/raspberry-pi/ja/%E3%83%A9%E3%82%BA%E3%83%99%E3%83%AA%E3%83%BC%E3%83%91%E3%82%A4%E3%83%BB%E3%83%94%E3%82%B3%E3%83%BB%E3%82%AA%E3%82%B7%E3%83%AD%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97%E3%81%A7%E9%9B%BB%E6%B0%97%E3%82%92/


基本的にgpio26がチャンネル1でマイナス信号は出力できない 入力も3vまでなら抵抗不要

import machine

import utime

led= machine.Pin(28, machine.Pin.OUT) 

while True:

    led.value(1)

    utime.sleep(0.1)

    led.value(0)

    utime.sleep(0.2)

をpico/wに書き込んでgpio28をscoppy化したpicoのgpio26につなぎ、グランドは共通化する

あとはチャンネル1で波形観察ができる

2024年6月1日土曜日

GPS /pic and esp01の連携成功


https://toccho.net/2022/07/26/neo6mv2-arduino/ :: 中華GPS

https://github.com/mikalhart/TinyGPSPlus/tree/master 上記ライブラリ

https://note.com/clever_elk255/n/nfd33282af18b :: 参考

--------------------------

 逆引きの162頁 mccのgetchとstdioのgetchがtype conflictしたのでmccをstdioに合わせて成功 TX,RXはpin-manager.cをみて了解した

/*****************************************

 *  Wi-Fi テストプログラム

 *  Wi-FiPC

*****************************************/

#include "mcc_generated_files/mcc.h"

/* 送信データ */

uint8_t Buf[] = "POT = x.xx Volt\r\n";

int result, i;

float Volt;

/* WiFi設定用コマンドデータ */

const uint8_t Mode[] = "AT+CWMODE=1\r\n";         // Station Mode

const uint8_t Join[] = "AT+CWJAP=\"184F32CF8BF3-2G\",\"??????\"\r\n";

const uint8_t Open[] = "AT+CIPSTART=\"TCP\",\"192.168.3.20\",8000\r\n";

const uint8_t Send[] = "AT+CIPSEND=17\r\n";       // 転送開始

const uint8_t Close[] = "AT+CIPCLOSE\r\n";        // サーバ接続解除

const uint8_t Shut[]  = "AT+CWQAP\r\n";           // Ap接続解除

/* 関数プロトタイプ */

void SendCmd(const uint8_t *cmd);

void ftostring(int seisu, int shousu, float data, uint8_t *buffer);

/***** メイン関数 *****/

void main(void)

{

    SYSTEM_Initialize();    // システム初期化

    /** APとサーバに接続 ***/

    SendCmd(Mode);          // Station Mode

    SendCmd(Join);          // APと接続

    __delay_ms(5000);       // 5sec待ち

    SendCmd(Open);          // サーバ(PC)と接続

    __delay_ms(2000);       // 2sec待ち    

    while (1)

    {

        /*** データ10回送信 ****/

        for(i=0; i<10; i++){

            LED_SetHigh();                  // 目印ON

            result = ADC_GetConversion(POT);// AD変換

            Volt = (result * 3.3) / 1023;   // 電圧に変換  システムを5vで駆動するときは5.0 !

            ftostring(1, 2, Volt, Buf+6);   // 文字列に変換

            /** Wi-Fi送信開始 ***/


            SendCmd(Send);          // 文字送信開始

            SendCmd(Buf);           // データ送信実行


            LED_SetLow();           // 目印オフ

            __delay_ms(3000);       // 繰り返し3秒待ち

        }

        /*** APとサーバから切り離し ****/

        SendCmd(Close);             // サーバ接続解除

        SendCmd(Shut);              // AP接続解除        

    }

}

/********************************

 * WiFiコマンド送信関数

 *  遅延挿入後戻る

 ********************************/

void SendCmd(const uint8_t *cmd)

{

    while(*cmd != 0)            // 文字列の終わりまで繰り返し

        EUSART_Write(*cmd++);   // 1文字送信し次の文字へ

    __delay_ms(1000);           // 1秒待ち 応答受信無視

}

/***********************************

* Floatから文字列へ変換

* 合計有効桁は8桁以下とすること

***********************************/

void ftostring(int seisu, int shousu, float data, uint8_t *buffer)

{

    int i;

    long dumy;


    if(shousu != 0)                         //小数部桁ありか

        buffer += seisu+shousu+1;           //全体桁数+小数点

    else                                    //小数部桁なしのとき

        buffer += seisu + shousu;           //全体桁数のみ

    buffer--;                               //配列ポインタ-1

    for(i=0; i<shousu; i++)                 //小数部を整数に変換

        data = data * 10;                   //10倍

    // dumyがオーバーフローすると変換不可(8桁が限界)

    dumy = (long) (data + 0.5);             //四捨五入して整数に変換

    for(i=shousu; i>0; i--) {           //小数桁数分繰り返し

        *buffer =(uint8_t)(dumy % 10)+'0';//数値を文字に変換格納

        buffer--;                           //格納場所下位から上位へ

        dumy /= 10;                         //次の桁へ

    }

    if(shousu != 0) {                       //小数桁0なら小数点なし

        *buffer = '.';                      //小数点を格納

        buffer--;                           //ポインタ-1

    }

    for(i=seisu; i>0; i--) {                //整数桁分繰り返し

        *buffer = (uint8_t)(dumy % 10)+'0';//数値を文字に変換格納

        buffer--;                           //ポインタ-1

        dumy /= 10;                         //次の桁へ

    }

}


まず以下のpythonコードでサーバをたちあげておく

#simple echo server

from os import terminal_size

import socket

server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

server_socket.bind(("192.168.3.20",8000))

server_socket.listen(1)

client_socket,client_address = server_socket.accept()

print("Connection from",client_address)

while True:

  data = client_socket.recv(1024)

  str_data = data.decode()

  if not data : break

  print("Received from client",str_data)

  # client_socket.send(data) # echo back function disabled by me

#client_address.close()

client_socket.close()

--------------------echo enable :: client.py-------------------------------------------

#client

import socket


client_socket = socket.socket()

client_socket.connect(("192.168.3.20",8000))

while True:

  data = input(">")

  client_socket.send(data.encode())

  if  not data:break

  newData = client_socket.recv(1024)

  print("Received from server:" ,str(newData.decode()))

client_socket.close()