Setting FlatCAM untuk milling PCB dengan CNC

  1. Buka file gerber untuk jalur PCB layer bawah biasanya file .GBL, atau buka layer atas biasanya file .GTL
  2. Buka file Excellon untuk lokasi pengeboran, biasanya file .XLN
  3. Selanjutnya jika layer yang akan digurat adalah layer bawah, perlu dibalik dengan perintah mirror. Biasanya dipilih di titk 0,0 pada sumbu X.
  4. Jika inggin menggunakan CNC untuk memotog PCB bisa buka file outline, biasanya file .GKO

Cara ubah desain eagle ke flatcam, bisa lihat artikel berikut: Eagle to FlatCAM

Isolation routing

  1. Buka file gerber, dengan klik 2x, misalnya file .GBL dan pilih tombol isolation routing.
Tombol Isolation Routing
Menu Isolation Routing

Isikan parameter tersebut, mulai dari ukuran milling (bor) 0.7 mm dengan jenis C1. Passes diisi 1 menandakan 1 kali guratan. Overlap biasanya 10%, jadi jika passesnya lebih dari 1, jaur yang overlaping 10% (Dalam hal ini jika milling 0.7mm, mmaka overlapnya 0.07mm). Centang bagian combine jika iki menyatikan file hasil geometry-nya. PAstikan untuk mencentang Check Validity untuk memastikan semua jalur dapat dibentuk geometry-nya. Jika sudah komplit isiannya, klik tombol [Generate Geometry]

File geometry akan tebentuk dan lanjutkan dengan membuat object CNC.

Isikan parqameter di atas untuk kasus bor 0.7mm s.d 0.8mm. Diameter mill adalah 0.7 dengan bentuk C1. Cut Z adalah seberapa dalam tembaga PCB akan dikelupas. Untuk PCB dengan tebal 1 oz, sejatinya adalah 0.035mm tebal tembaganya. Namun, saat mill sudah mulai tumpul atau PCB tidak rata, maka di atas ditambahkan dalamnya guratan sebesar -0.050mm. Centang Multi-Depth agar guratan pertama adalah -0.040 dilanjutkan guratan kedua untuk membersikan sisa tembaga -0.050mm.

Travel Z adalah seberapa tinggi mill bergerak saat pindah ke titik lain. Pastikan tingginya melebihi dari ketebalan PCB. Untuk PCB 1 oz, bisa gunakan 2 atau lebih, dimana tebal PCB hanya 1.78mm. Feedrate X-Y adalah kecepatan gerak mill. Gunakan 180 mm/s untuk kecepatan sedang. Feedrate Z 60 mm/s untuk kecepatan pengeboran sedang. Untuk CNC yang ketinggiannya kurang dari 5 cm, disarankan mengganti End Move Z menjadi 10mm. Lanjutkan dengan klil tombol [Generate CNCJob Object]

Pembuatan Kode GCODE

Menu CNC Job Object

Lanjutkan dengan membuat kode GCODE untuk dapat dibaca oleh CNC. Cukup dengan membuka menu CNC Job Object dan klil tombol [Save CNC Code]

Excellon Object, atau titik pengeboran

Excellon Object

Buka menu Excellon Object, tentukan lubang dengan ukuran berapa yang akan dibor. Jika semua lubang, cukup klik tanda pagar, semua lubang akan terpilih. Lanjutkan dengan klik tombol [Drilling Tool]

Pembuatan CNC Object untuk pengeboran

Pilih ukuran lubang PCB atau cukup klik # untuk pilih semua lubang. isikan Cut-Z dengan tebal PCB, untuk pcb dengan tebal 1 oz bisa gunakan -1,78mm atau -1,80mm. Travel Z gunakan 2mm atau sesuaikan dengan ketebalan PCB. Feedrate Z atau kecepatan pengeboran, isikan 120mm/s untuk kecepatan tinggi atau 60mm/s untuk kecepatan sedang. Ganti tool change ke 10mm dan End move Z ke 10mm untuk CNC ketinggian rendah. Klik [Generate CNCjob Object] untuk membuat object CNC

Pembuatan GCode untuk pelubangan PCB

Cukup Klik Save CNC Code simpan GCode

Proses Autoleveling

Proses ini digunakan untuk mendeteksi ketinggian PCB yang nantinya disematkan di GCode. Proses ini dibantu dengan software autoleveler.

Tampilan Autoleveller versi 7

Pilih software cnc yang akan digunakan, misalnya Mach3. Buka file GCODE dengan extensi .tap atau .nc maka ukuran otomatis akan msuk ke setting. Isikan ZFeed dengan 100mm/s untuk kecepatan mill mendeteksi ketinggian. Probe depth -1, sehingga saat kedalaman -1mm tidak ditemukan tambaga, maka dianggap jarak tembaga dengan probe maksimal adalah 1mm. Probe clearance diisi 2mm untuk probe bisa bergerak. Isikan nilai ini > ketebalan PCB. Probe spacing 10mm untuk melakukan probe 10mm atau isikan 5mm untuk melakukan probing setiap 5mm. Isikan Z safe height dengan 10mm untuk mesin CNC yang ketinggian rendah. Klik [Create Levelled GCode] untuk membuat kode GCode yang sudah tebenam autoleveling.

Pemotongan ukuran PCB dengan outline

Buka file outline, biasanya file .GKO, dan pilih tombol [Cutout Tools]. Selanjutnya mebu berikut akan muncul.

Menu Cutout PCB

Isikan parameter sesuai dengan gambar di atas. Pilih Kind: Gerber, Type:Gerber. Set diamater mill 0.8mm atau sesuaikan dengan ukuran mill yang digunakan. isikan Cut Z dengan ketebalan PCB, misalnya -1.8mm untuk PCB 1 oz. Dianjutkan untuk menggunakan Multi-depth untuk mill yang berukuran kecil dengan nilai 3mm s.d 5mm dan margin 0.1mm atau sesuai dengan keinginan sebagai batas pemotongan. Isikan Gap size 1mm agar PCB mudah dilepas, atau setidaknya sesuai ukuran mill yang digunakan. Pilih Gaps: LR untuk gap di kiriri dan kanan. LAnjutkan dengan [Generate Geometry] selanjutnya buat Object CNC dan simpan kode CNC sesuai contoh geomatry lain untuk pengeboran.

Setting konfigurasi cepat

Gunakan setting berikut untuk penyetikan cepat dengan klik menu File => Backup => Import Setting dengan file berikut. File berikut untuk ketebalan PCB 1oz dengan mill 0.8mm

Password untuk semua file:latiful hayat

Jika letak lubang PCB tidak sesuai dengan jalur, cek artikel berikut: Setting Trailing Zeros

Eagle uses Trailing Zeros in its Excellon number format but does not properly report this format in the Excellon file. To tell FlatCAM to use this format by default set this system option excellon_zeros to T by using the set_sys command in the Shell Command Line Interface as shown below:

Ketikkan set_sys excellon_zeros T pada Cmd Line lalu restart FlatCAM

Eagle ke FlatCam JLCPCB atau PCBWAY

Panduan cepat untuk mengekspor desain PCB dari Eagle dan mengimpornya ke FlatCAM. Panduan ini dibuat dengan Eagle versi 7.2.0 Light dan FlatCAM 8.2.

Sebagian besar desain dimulai dengan skema rangkaian:

Kemudian dengan meng-klik File→Switch to board, editor papan PCB terbuka dan kemudian menyelesaikan tata letak rangkaian:

Untuk ekspor file cam bor, buka File→CAM Processor lagi dan pilih setelan pada gambar di bawah. Pilih EXCELLON_24 untuk bagian Device. Berikan ekstensi drills.drd pada nama file bor jika perlu. Klik Proses Job untuk mengekspor.

Kita sudah selesai dengan Eagle. Sekarang mari beralih ke FlatCAM.

Eagle menggunakan Trailing Zeros dalam format angka Excellon, format ini perlu dilaporkan dengan benar di FlatCaM dengan cara berikut:

_images/eagle_example_5.png

Perubahan pada opsi sistem akan disetel saat memulai ulang, maka FlatCam perlu dijalankan ulang.

Sekarang cukup buka file Gerber dan Excellon yang diekspor dari Eagle.

Cara setting flatmac dapat dilihat di artikel berikut:

Sumber: http://flatcam.org/manual/eaglehowto.html

Jika ingin mengekspor untuk file gerber di layanan produsen PCB semisal JLCPCB atau PCBWAY, gunakan file konfigurasi CAM berikut: Cara Setting FlatCAM

  1. CAM JLCPCB
  2. CAM PCBWAY

Antarmuka Port Serial dengan C++

Gunakan Class Serial berikut:

//File: Serial.h
#ifndef SERIALCLASS_H_INCLUDED
#define SERIALCLASS_H_INCLUDED

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

class Serial
{
    private:
        //Serial comm handler
        HANDLE hSerial;
        //Connection status
        bool connected;
        //Get various information about the connection
        COMSTAT status;
        //Keep track of last error
        DWORD errors;

    public:
        //Initialize Serial communication with the given COM port
        Serial(char *portName);
        //Close the connection
        ~Serial();
        //Read data in a buffer, if nbChar is greater than the
        //maximum number of bytes available, it will return only the
        //bytes available. The function return -1 when nothing could
        //be read, the number of bytes actually read.
        int ReadData(char *buffer, unsigned int nbChar);
        //Writes data from a buffer through the Serial connection
        //return true on success.
        bool WriteData(char *buffer, unsigned int nbChar);
        //Check if we are actually connected
        bool IsConnected();


};

#endif // SERIALCLASS_H_INCLUDED

//File: Serial.cpp
#include "Serial.h"

Serial::Serial(char *portName)
{
    //We're not yet connected
    this->connected = false;

    //Try to connect to the given port throuh CreateFile
 #if _MSC_VER && !__INTEL_COMPILER
    const size_t cSize = strlen(portName) + 1;
    wchar_t* wc = new wchar_t[cSize];
    mbstowcs_s(NULL, wc, cSize, portName, cSize);
    this->hSerial = CreateFile(wc,
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
#else
    //Try to connect to the given port throuh CreateFile
    this->hSerial = CreateFile(portName,
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
#endif

    //Check if the connection was successfull
    if(this->hSerial==INVALID_HANDLE_VALUE)
    {
        //If not success full display an Error
        if(GetLastError()==ERROR_FILE_NOT_FOUND){

            //Print Error if neccessary
            printf("ERROR: Handle was not attached. Reason: %s not available.\n", portName);

        }
        else
        {
            printf("ERROR!!!");
        }
    }
    else
    {
        //If connected we try to set the comm parameters
        DCB dcbSerialParams = {0};

        //Try to get the current
        if (!GetCommState(this->hSerial, &dcbSerialParams))
        {
            //If impossible, show an error
            printf("failed to get current serial parameters!");
        }
        else
        {
            //Define serial connection parameters for the arduino board
            dcbSerialParams.BaudRate=CBR_9600;
            dcbSerialParams.ByteSize=8;
            dcbSerialParams.StopBits=ONESTOPBIT;
            dcbSerialParams.Parity=NOPARITY;
            //Setting the DTR to Control_Enable ensures that the Arduino is properly
            //reset upon establishing a connection
            dcbSerialParams.fDtrControl = DTR_CONTROL_ENABLE;

             //Set the parameters and check for their proper application
             if(!SetCommState(hSerial, &dcbSerialParams))
             {
                printf("ALERT: Could not set Serial Port parameters");
             }
             else
             {
                 //If everything went fine we're connected
                 this->connected = true;
                 //Flush any remaining characters in the buffers
                 PurgeComm(this->hSerial, PURGE_RXCLEAR | PURGE_TXCLEAR);
                 //We wait 2s as the arduino board will be reseting
                 Sleep(2000);
             }
        }
    }

}

Serial::~Serial()
{
    //Check if we are connected before trying to disconnect
    if(this->connected)
    {
        //We're no longer connected
        this->connected = false;
        //Close the serial handler
        CloseHandle(this->hSerial);
    }
}

int Serial::ReadData(char *buffer, unsigned int nbChar)
{
    //Number of bytes we'll have read
    DWORD bytesRead;
    //Number of bytes we'll really ask to read
    unsigned int toRead;

    //Use the ClearCommError function to get status info on the Serial port
    ClearCommError(this->hSerial, &this->errors, &this->status);

    //Check if there is something to read
    if(this->status.cbInQue>0)
    {
        //If there is we check if there is enough data to read the required number
        //of characters, if not we'll read only the available characters to prevent
        //locking of the application.
        if(this->status.cbInQue>nbChar)
        {
            toRead = nbChar;
        }
        else
        {
            toRead = this->status.cbInQue;
        }

        //Try to read the require number of chars, and return the number of read bytes on success
        if(ReadFile(this->hSerial, buffer, toRead, &bytesRead, NULL) && bytesRead != 0)
        {
            return bytesRead;
        }

    }

    //If nothing has been read, or that an error was detected return -1
    return -1;

}


bool Serial::WriteData(char *buffer, unsigned int nbChar)
{
    DWORD bytesSend;

    //Try to write the buffer on the Serial port
    if(!WriteFile(this->hSerial, (void *)buffer, nbChar, &bytesSend, 0))
    {
        //In case it don't work get comm error and return false
        ClearCommError(this->hSerial, &this->errors, &this->status);

        return false;
    }
    else
        return true;
}

bool Serial::IsConnected()
{
    //Simply return the connection status
    return this->connected;
}


Berikut contoh koneksi pengiriman data

#include <iostream>
#include "windows.h"
#include "Serial.h"

#include <thread>
#include <chrono>

using namespace std;

void delay(int ms){
    std::this_thread::sleep_for (std::chrono::milliseconds(ms));
}

int main(int argc, char** argv) {

    char alamatPort[] = "\\\\.\\COM7";
    Serial* s = new Serial(alamatPort);

	char dataOn[256] = "on1\n"; //"Nyala!";
	char dataOff[256] = "off0\n"; //"mati!";

	cout<<"isikan angka 1 untuk menyalakan, atau 0 untuk mematikan"<<endl;


	int jawab;
	do{
        cin>>jawab;;

        if(jawab==0)
            s->WriteData(dataOff, sizeof(dataOff));
        if(jawab==1)
            s->WriteData(dataOn, sizeof(dataOn));
        if(jawab==2)
            for(int a=0;a<5;a++){
                s->WriteData(dataOn, sizeof(dataOn));
                delay(500);
                s->WriteData(dataOff, sizeof(dataOff));
                delay(500);
            }
	}while(jawab<3);

	return 0;
}

Berikut contoh untuk mengirim dan menerima data

#include <iostream>
#include <stdio.h>
#include <tchar.h>
#include "Serial.h" // Library described above
#include <string>


/* run this program using the console pauser or add your own getch, system("pause") or input loop */
char alamatPort[] = "\\\\.\\COM7";
Serial* SP = new Serial(alamatPort);    // adjust as needed

void* baca(void* data)
{

    char incomingData[256] = "";            // don't forget to pre-allocate memory
    //printf("%s\n",incomingData);
    int dataLength = 256;
    int readResult = 0;


    while (SP->IsConnected())
    {
        readResult = SP->ReadData(incomingData, dataLength);
        if (readResult > 0) {
            printf("%s\n", incomingData);
        }
        //printf("Bytes read: (-1 means no data available) %i\n",readResult);

        //std::string test(incomingData);

        //printf("%s",incomingData);
        //test = "";

        Sleep(500);
    }
    return NULL;
}

void* tulis(void* data)
{
    while (SP->IsConnected())
    {
        char outgoingData[256] = "";
        char keluar[256] = "keluar";
        int dataLength = sizeof(outgoingData);        // don't forget to pre-allocate memory
        scanf_s("%255s", outgoingData, dataLength);

        if (outgoingData != "")
        {
            if (strcmp(outgoingData, "OK") == 0) {
                printf("Pengiriman selesai\n");
                return NULL;

            }
            if (SP->WriteData(outgoingData, dataLength))
            {
                printf("Data send:%s\n", outgoingData);
            }
        }

        Sleep(500);
    }
    // do stuff...
    return NULL;
}

#if _MSC_VER && !__INTEL_COMPILER
#include <thread>

int main(int argc, char** argv) {
    printf("Welcome to the serial test app!\n\n");
    if (SP->IsConnected())
        printf("Serial sudah terhubung\n");
    int status;
    std::thread thrd_1(baca,(void*)0);
    std::thread thrd_2(tulis, (void*)0);

    thrd_1.join();
    thrd_2.join();

}
#else
// thread example
#include <pthread.h>

int main(int argc, char** argv) {
    printf("Welcome to the serial test app!\n\n");
    if (SP->IsConnected())
        printf("Serial sudah terhubung\n");

    pthread_t thrd_1;
    pthread_t thrd_2;
    int status;

    pthread_create(&thrd_1, NULL, baca, (void*)0);
    pthread_create(&thrd_2, NULL, tulis, (void*)0);

    pthread_join(thrd_1, (void**)&status);
    pthread_join(thrd_2, (void**)&status);

    printf("Terima kasih");

    return 0;
}
#endif

Gender Konektor DB9 pada RS232

DTE vs DCE

DTE adalah Data Terminal Equipment, dimana sumbaer data dan pengolahannya ada di bagian ini. Untuk koneksi SPI ini dinamakan Master. Sedangkan DCE atau Data Circuit terminating Equipment adalah perangkat periferal dari DTE. Ini dinamakan Slave pada antarmuka SPI.

DTE dan DCE

Gender koneksi DTE dibanding DCE

Pada koneksi DTE dalam banyak kasus biasanya jenis MALE, sedangkan untuk DCE adalah yang female. Namun tidak semuanya seperti ini, harus pintar membaca petunjuk atau datasheet.

Image result for de-9 pinout female male
Male untuk DTE dan Female untuk DCE

Pinout

Untuk koneksi RS232 dasar, biasanya hanya perlu Rx, Tx dan Ground. Beberapa peralatan mungkin memerlukan pin kontrol tambahan. Berikut bagaimana pengaturan pin menempatkan Tx ke Rx, DTR ke DSR, dan RTS ke CTS.

Pinout DB9 pada RS232 untuk Male (DTE) dan Female (DCE)

Contoh modul untuk DTE dan DCE

테크 선전 아두이노, 라즈베리파이, 마이크로비트
Modul untuk DCE dengan konektor Female
Amazon.com: NulSom Inc. Ultra Compact RS232 to TTL ...
Modul untuk DTE dengan konektor Male

Null Modem

Null modem dibutuhkan untuk koneksi DTE ke DTE (Male – Male) atau DCE ke DCE (Female-Female)

RS232 cable
Null Modem untuk Male to Male (DTE to DTE)

Panelisasi PCB

Saat ukuran desain PCB kecil, katakanlah 2×3 cm, dan akan dibuat pada PCB dengan ukuran 10 x 10 cm, maka desain PCB dapat dibuat panel. PCB ukuran 10 x 10 akan dapat menampung setidaknya 12 desain PCB 2×3 cm.

Buka pada Panel Properties dan isikan ukuran PCB 100mm x 100mm. Tentukan jarak antar desain PCB 2mm.
Buka folder gerber pada menu Add Gerber Folder
kanan pada instance lalu pilih menu Add Instance. Lakukan 11 kali, hingga instance menjadi 12.
Pilih Autopack agar instance (desain board PCB) tertata otomatis.
Tambahkan Breaktab dengan Insert Breaktabs, untuk menyanbungkan instance. Atau pilih Create Breaktabs untuk penambahan Breaktab secara otomatis
Ekspor hasil gerber yang sudah digabung (Merged) ke folder
Tampilan proses eksport
Cek Gambar hasil gerber. Jika ada yang rusak, perlu diulangi.

Zip semua file gerber dan siap untuk dimasukkan ke percetakan atau dibuka dengan FlatCam untuk dicetak lewat CNC. Atau dapat juga dicetak di printer untuk metode toner transfer dan photoresist.