REKLAMA

Example5_28BYJ48_PIC16F1459_mikroC.zip

Jednodniowe DIY - obrotowa platforma (2 osie) na USB pod kamerkę ze śmieci

https://obrazki.elektroda.pl/6028895200_1549881230_thumb.jpg Witajcie moi drodzy To dziwne coś powstało w jeden dzień. Byłem ciekawy na ile da się złożyć obrotową platformę pod kamerkę z tego co jest pod ręką. Platforma posiada dwie osie obrotu: prawo-lewo oraz góra-dół. Całość złożona jest: - kamerki PAL na 12V - konwertera "PAL na USB" aby móc odbierać obraz na PC - kontrolera USB na PIC16F1459 - dwóch silniczków 28BYJ-48 (jeden widoczny na zdjęciu, drugi jest w platformie) - dodatkowej płytki ze złączami - odpadów, w tym starego PCB... Całość pozwala zdalnie zobaczyć co się dzieje w całym pokoju, pod warunkiem że podłączę się do tamtejszego komputera przez program typu TeamViewer (i też tak robię). Opis konstrukcji Konstrukcja powstała w jeden dzień z tego co było w szufladzie oraz z innych odpadów. Nie robiłem do niej żadnego schematu (ani elektronicznego, ani mechanicznego). Do samej konstrukcji mechanicznej użyłem tylko: - dwa silniki 28BYJ-48 (najtańsze od chińczyków) - płyta główna z monitora CRT (a w zasadzie sam laminat - z elektrośmieci) - plastikowe opakowanie (ze śmieci...) - zestaw śrubek M2, M3, M4 (z szuflady) Od strony elektronicznej użyłem: - dwa sterowniki dla 28BYJ-48 (te z LEDami, najtańsze od chińczyków) - płytkę uniwersalną z kondensatorem, 7805, złączami na wyjście video PAL oraz wejście zasilania jack 12V - moją płytkę PIC16F1459 ze złączem USB (odpowiada ona za komunikację i steruje silnikami krokowymi) Od strony "kamerkowej" użyłem: - kamera PAL FPV Camera 700TVL (najtańsza od chińczyków) - konwerter "PAL do USB" Video DVR (jego kupowałem w Polsce, chyba na słynnym portalu aukcyjnym) Całość wymaga zasilacza 12V ze względu na to, że takiego napięcia potrzebuje kamerka AL FPV Camera 700TVL. Ramię i jego łączenia z silniczkami Ramię zostało zrobione z laminatu z płyty głównej od monitora CRT, który wcześniej oczyściłem z elementów i nadmiaru cyny. Wszystko zostało docięte na oko i połączone śrubkami. W jednym miejscu użyłem również dwóch małych kątowniczków. Największym problemem okazały się mocowania do silników, ponieważ ich rotory nie mają otworu na śrubkę tak jak inne popularne silniczki, więc musiałem poradzić sobie "na dziko" i dopasować je na wcisk: https://obrazki.elektroda.pl/5500141600_1549878819_thumb.jpg Całością się już trochę bawiłem i na razie trzyma się dość dobrze, ale nie zdziwię się, jak wkrótce się rozwali. Software (sterowanie) Sterowanie odbywa się poprzez USB. Sercem konstrukcji jest PIC16F1459. Jego firmware napisałem w mikroC PRO for PIC. Na firmware składa się komunikacja USB (odbiór pakietów-rozkazów jak ma się poruszyć silnik) oraz samo sterowanie silnikiem. Tak wygląda szkielet programu (główna pętla w main oraz przerwanie od USB): unsigned char readbuff absolute 0x040; // Buffers should be in USB RAM, please consult datasheet unsigned char writebuff absolute 0x140; void interrupt(){ USB_Interrupt_Proc(); // USB servicing is done inside the interrupt } void main(void){ (...) while(1) { while(HID_Read()) { // tu 'readbuff' zawiera pakiet przeslany przez USB if(readbuff==0) { // itp itd } // itp itd } (...) } } Dla silnika krokowego przygotowałem własny zestaw funkcji który obejmuje: /* Inicjuje strukture motor_t, jako argumenty przyjmuje wskaźniki na banki (PORTA, PORTB, itp) oraz numery bitów. Czyli silnik może być sterowany przez 4 dowolne piny. */ void MOTOR_Init(motor_t *m, int *bank1, int bit1, int *bank2, int bit2, int *bank3, int bit3, int *bank4, int bit4); /* Ustawia komende przejścia danej ilości kroków w danym kierunku. */ void MOTOR_GoTo(motor_t *m, int dir, int loops); /* Zatrzymuje silnik (komenda stop) */ void MOTOR_Stop(motor_t *m); /* Aktualizuje ruch silnika, nie może być wołane za często. Ja wołam z odstępem Delay_us(2000); */ void MOTOR_Run(motor_t *m); Funkcje nie były tworzone z myślą o wydajności, lecz o przydatności. Biblioteka obsługuje dowolną ilość silniczków, deklaruje się je tak: motor_t motorH; motor_t motorV; Potem można na nich używać funkcji MOTOR_*. Po stronie komputera znajduje się z kolei aplikacja napisana w Visual Studio. https://obrazki.elektroda.pl/5855799100_1546299554_thumb.jpg Aplikacja ma dwa zestawy przycisków prawo-lewo góra-dół. Jeden pozwala na precyzyjne sterowanie silnikami, drugi po jednym kliknięciu wykonuje obrót o większy kąt. Software (kamerka) Użyta kamerka to FPV Camera 700TVL. Na jej wyjściu jest sygnał PAL, który dopiero potem idzie do konwertera PAL na USB i poprzez USB odbierany jest w komputerze z pomocą odpowiedniego programu. Nic nie stoi tu na przeszkodzie by użyć normalną kamerkę USB, ale tak jak napisałem - użyłem tego co miałem pod reką. Użyty program to honestech VHS to DVD 2.0 SE, ale do konwertera PAL->USB (PAL/VHS NA PC VIDEO GRABBER EASY CAP) który używam pasują też chyba inne aplikacje. Sam program wygląda tak: https://obrazki.elektroda.pl/7351750700_1549879350_thumb.jpg https://obrazki.elektroda.pl/6936549600_1549879350_thumb.jpg W celu najlepszego odbioru obrazu z kamerki należy odpowiednio go skonfigurować, tzn. wybrać czy sygnał wejściowy to PAL, czy SECAM, oraz jaki dokładnie podtyp PAL/SECAM https://obrazki.elektroda.pl/5040749700_1546303094_thumb.jpg W przypadku złego ustawienia w programie obraz może być wyświetlany niepoprawnie: https://obrazki.elektroda.pl/6805337500_1546303140_thumb.jpg https://obrazki.elektroda.pl/3060785200_1546303139_thumb.jpg Konwerter PAL->USB wygląda tak: https://obrazki.elektroda.pl/3763915700_1549879534_thumb.jpg https://obrazki.elektroda.pl/9382782800_1549879535_thumb.jpg Sam program (honestech VHS to DVD 2.0 SE) pobrałem z internetu, ponieważ do kupionego przeze mnie konwertera PAL na USB nie była dołączona żadna płytka, ani nawet instrukcja. PCB sterowania przez USB na PIC16F1459 Tę płytkę chyba już kiedyś wrzucałem na elektrodę, ale przypomnę tu coś o niej. Na pokładzie znajduje się 8-bitowy PIC16F1459 (14kB pamięci Flash, 1kB RAM) ze sprzętowym wsparciem USB. Na płytce nie ma żadnego rezonatora kwarcowego, ponieważ PIC16F1459 ma wewnętrzny rezonator wystarczająco dobry do użycia go przy komunikacji USB. Płytka w Eagle: http://obrazki.elektroda.pl/8510604300_1472728542_thumb.jpg Warstwa opisowa: http://obrazki.elektroda.pl/8392202100_1472728521_thumb.jpg Wykonanie: https://obrazki.elektroda.pl/4699329500_1546293201_thumb.jpg Całość zrobiłem parę lat temu z pomocą metody żelazkowej. Podsumowanie Zdawać by się mogło, że nawet takie proste sterowanie kamerką w dwóch osiach wymaga dużo pracy i nakładów finansowych, ale jak widać tak nie jest. Sam jestem zaskoczony, że udało mi się to w jeden dzień złożyć z tego, co było pod ręką, i że całość w takiej formie jak na zdjęciach ma prawo trzymać się kupy :D Kosztorys Dość trudno tu będzie przedstawić koszty całości, ale spróbuję wypisać te ceny które znam. FPV Camera 700TVL- 20 zł (chińskie A) 28BYJ48 z płytką sterownika - 2*6=12 zł (chińskie A) PAL/VHS NA PC VIDEO GRABBER EASY CAP - 20 zł (polski portal aukcyjny) PIC16F1459 - 10 zł (tme) Laminat, drobnica, zasilacz 12V - z szuflady Ale tak naprawdę całość kosztowała mnie 0 złotych i powstała z tego, co było pod ręką. Załączniki: - program na PC (z kodem źródłowym!): 952624 - firmware na PIC (z kodem źródłowym!): 952625 - sam kod obsługi silnika krokowego: 952623 - pliki Eagle płytki od PIC16F1459: 952622 - pliki pdf do termotransferu od w/w plytki: 952621


Pobierz plik - link do postu
  • Example5_28BYJ48_PIC16F1459_mikroC.zip
    • Example5_Stepper.mcppi_callertable.txt
    • Example5_Stepper.asm
    • Example5_Stepper.mcppi
    • Example5_Stepper.cp
    • Example5_Stepper.user.dic
    • USBdsc.cp
    • Example5_Stepper.dbg
    • Example5_Stepper.mcl
    • Example5_Stepper.brk
    • USBdsc.c.ini
    • Example5_Stepper.lst.ini
    • Example5_Stepper.log
    • Example5_Stepper.lst
    • USB.xml
    • Example5_Stepper.bmk
    • USBdsc.asm
    • Example5_Stepper.dct
    • Example5_Stepper.ini
    • Example5_Stepper.cfg
    • Example5_Stepper.c
    • Example5_Stepper.wch
    • Example5_Stepper.txt
    • USBdsc.c
    • Example5_Stepper.hex
    • Example5_Stepper.dlt
    • Example5_Stepper.dic
    • Example5_Stepper.c.ini
    • USBdsc.mcl


Example5_28BYJ48_PIC16F1459_mikroC.zip > Example5_Stepper.txt

main
HID_Enable
GetMaxStrignDscIndex
GetMaxIndexInDevDsc
GetMaxIndexInConfigDsc
USB_Device_Init
USB_Init_Desc
USB_Configure
USB_Attach_Device
USB_Configure
USB_Enable_Interrupts
HID_Read
Gen_Read
USB_Handle_Busy
USB_Transfer_Packet
interrupt
USB_Interrupt_Proc
USB_Wake_From_Suspend
USB_Clear_Interrupt
USB_Device_Init
USB_Init_Desc
USB_Configure
USB_Suspend
USB_Stall_Handler
USB_CtrlTrf_Setup_Handler
USB_Check_Std_Request
USB_Get_Dsc_Handler
Mul_16X16_U
USB_Set_Cfg_Handler
USB_CB_Init_EP
USB_Get_Status_Handler
USB_Std_Feature_Req_Handler
USB_CB_Check_Other_Req
USB_Check_HID_Request
USB_CtrlEP_Service_Complete
USB_CtrlTrf_Tx_Service
USB_CtrlTrf_Out_Handler
USB_CtrlTrf_Rx_Service
USB_Prepare_Next_Setup_Trf
USB_CtrlTrf_In_Handler
USB_CtrlTrf_Tx_Service
USB_Prepare_Next_Setup_Trf


Example5_28BYJ48_PIC16F1459_mikroC.zip > USBdsc.c

void USB_Init_Desc();
const unsigned int USB_VENDOR_ID = 0x1234;
const unsigned int USB_PRODUCT_ID = 0x0001;
const char USB_SELF_POWER = 0xC0; // Self powered 0xC0, 0x80 bus powered
const char USB_MAX_POWER = 50; // Bus power required in units of 2 mA
const char HID_INPUT_REPORT_BYTES = 64;
const char HID_OUTPUT_REPORT_BYTES = 64;
const char USB_TRANSFER_TYPE = 0x03; //0x03 Interrupt
const char EP_IN_INTERVAL = 1;
const char EP_OUT_INTERVAL = 1;

const char USB_INTERRUPT = 1;
const char USB_HID_EP = 1;
const char USB_HID_RPT_SIZE = 33;

/* Device Descriptor */
const struct {
char bLength; // bLength - Descriptor size in bytes (12h)
char bDescriptorType; // bDescriptorType - The constant DEVICE (01h)
unsigned int bcdUSB; // bcdUSB - USB specification release number (BCD)
char bDeviceClass; // bDeviceClass - Class Code
char bDeviceSubClass; // bDeviceSubClass - Subclass code
char bDeviceProtocol; // bDeviceProtocol - Protocol code
char bMaxPacketSize0; // bMaxPacketSize0 - Maximum packet size for endpoint 0
unsigned int idVendor; // idVendor - Vendor ID
unsigned int idProduct; // idProduct - Product ID
unsigned int bcdDevice; // bcdDevice - Device release number (BCD)
char iManufacturer; // iManufacturer - Index of string descriptor for the manufacturer
char iProduct; // iProduct - Index of string descriptor for the product.
char iSerialNumber; // iSerialNumber - Index of string descriptor for the serial number.
char bNumConfigurations; // bNumConfigurations - Number of possible configurations
} device_dsc = {
0x12, // bLength
0x01, // bDescriptorType
0x0200, // bcdUSB
0x00, // bDeviceClass
0x00, // bDeviceSubClass
0x00, // bDeviceProtocol
8, // bMaxPacketSize0
USB_VENDOR_ID, // idVendor
USB_PRODUCT_ID, // idProduct
0x0001, // bcdDevice
0x01, // iManufacturer
0x02, // iProduct
0x00, // iSerialNumber
0x01 // bNumConfigurations
};

/* Configuration 1 Descriptor */
const char configDescriptor1[]= {
// Configuration Descriptor
0x09, // bLength - Descriptor size in bytes
0x02, // bDescriptorType - The constant CONFIGURATION (02h)
0x29,0x00, // wTotalLength - The number of bytes in the configuration descriptor and all of its subordinate descriptors
1, // bNumInterfaces - Number of interfaces in the configuration
1, // bConfigurationValue - Identifier for Set Configuration and Get Configuration requests
0, // iConfiguration - Index of string descriptor for the configuration
USB_SELF_POWER, // bmAttributes - Self/bus power and remote wakeup settings
USB_MAX_POWER, // bMaxPower - Bus power required in units of 2 mA

// Interface Descriptor
0x09, // bLength - Descriptor size in bytes (09h)
0x04, // bDescriptorType - The constant Interface (04h)
0, // bInterfaceNumber - Number identifying this interface
0, // bAlternateSetting - A number that identifies a descriptor with alternate settings for this bInterfaceNumber.
2, // bNumEndpoint - Number of endpoints supported not counting endpoint zero
0x03, // bInterfaceClass - Class code
0, // bInterfaceSubclass - Subclass code
0, // bInterfaceProtocol - Protocol code
0, // iInterface - Interface string index

// HID Class-Specific Descriptor
0x09, // bLength - Descriptor size in bytes.
0x21, // bDescriptorType - This descriptor's type: 21h to indicate the HID class.
0x01,0x01, // bcdHID - HID specification release number (BCD).
0x00, // bCountryCode - Numeric expression identifying the country for localized hardware (BCD) or 00h.
1, // bNumDescriptors - Number of subordinate report and physical descriptors.
0x22, // bDescriptorType - The type of a class-specific descriptor that follows
USB_HID_RPT_SIZE,0x00, // wDescriptorLength - Total length of the descriptor identified above.

// Endpoint Descriptor
0x07, // bLength - Descriptor size in bytes (07h)
0x05, // bDescriptorType - The constant Endpoint (05h)
USB_HID_EP | 0x80, // bEndpointAddress - Endpoint number and direction
USB_TRANSFER_TYPE, // bmAttributes - Transfer type and supplementary information
0x40,0x00, // wMaxPacketSize - Maximum packet size supported
EP_IN_INTERVAL, // bInterval - Service interval or NAK rate

// Endpoint Descriptor
0x07, // bLength - Descriptor size in bytes (07h)
0x05, // bDescriptorType - The constant Endpoint (05h)
USB_HID_EP, // bEndpointAddress - Endpoint number and direction
USB_TRANSFER_TYPE, // bmAttributes - Transfer type and supplementary information
0x40,0x00, // wMaxPacketSize - Maximum packet size supported
EP_OUT_INTERVAL // bInterval - Service interval or NAK rate
};

const struct {
char report[USB_HID_RPT_SIZE];
}hid_rpt_desc =
{
{0x06, 0x00, 0xFF, // Usage Page = 0xFF00 (Vendor Defined Page 1)
0x09, 0x01, // Usage (Vendor Usage 1)
0xA1, 0x01, // Collection (Application)
// Input report
0x19, 0x01, // Usage Minimum
0x29, 0x40, // Usage Maximum
0x15, 0x00, // Logical Minimum (data bytes in the report may have minimum value = 0x00)
0x26, 0xFF, 0x00, // Logical Maximum (data bytes in the report may have maximum value = 0x00FF = unsigned 255)
0x75, 0x08, // Report Size: 8-bit field size
0x95, HID_INPUT_REPORT_BYTES,// Report Count
0x81, 0x02, // Input (Data, Array, Abs)
// Output report
0x19, 0x01, // Usage Minimum
0x29, 0x40, // Usage Maximum
0x75, 0x08, // Report Size: 8-bit field size
0x95, HID_OUTPUT_REPORT_BYTES,// Report Count
0x91, 0x02, // Output (Data, Array, Abs)
0xC0} // End Collection
};

//Language code string descriptor
const struct {
char bLength;
char bDscType;
unsigned int string[1];
} strd1 = {
4,
0x03,
{0x0409}
};


//Manufacturer string descriptor
const struct{
char bLength;
char bDscType;
unsigned int string[16];
}strd2={
34, //sizeof this descriptor string
0x03,
{'M','i','k','r','o','e','l','e','k','t','r','o','n','i','k','a'}
};

//Product string descriptor
const struct{
char bLength;
char bDscType;
unsigned int string[23];
}strd3={
32, //sizeof this descriptor string
0x03,
{'U','S','B',' ','H','I','D',' ','L','i','b','r','a','r','y'}
};

//Array of configuration descriptors
const char* USB_config_dsc_ptr[1];

//Array of string descriptors
const char* USB_string_dsc_ptr[3];

void USB_Init_Desc(){
USB_config_dsc_ptr[0] = & configDescriptor1;
USB_string_dsc_ptr[0] = (const char*) & strd1;
USB_string_dsc_ptr[1] = (const char*) & strd2;
USB_string_dsc_ptr[2] = (const char*) & strd3;
}


Example5_28BYJ48_PIC16F1459_mikroC.zip > Example5_Stepper.mcppi_callertable.txt

main
HID_Enable
GetMaxStrignDscIndex
GetMaxIndexInDevDsc
GetMaxIndexInConfigDsc
USB_Device_Init
USB_Init_Desc
USB_Configure
USB_Attach_Device
USB_Configure
USB_Enable_Interrupts
MOTOR_Init
PORT_Init
PORT_Set
PORT_SetTrue
PORT_SetFalse
HID_Read
Gen_Read
USB_Handle_Busy
USB_Transfer_Packet
MOTOR_Run
PORT_Set
PORT_SetTrue
PORT_SetFalse
MOTOR_RunInternal
PORT_Set
PORT_SetTrue
PORT_SetFalse
MOTOR_Stop
interrupt
USB_Interrupt_Proc
USB_Wake_From_Suspend
USB_Clear_Interrupt
USB_Device_Init
USB_Init_Desc
USB_Configure
USB_Suspend
USB_Stall_Handler
USB_CtrlTrf_Setup_Handler
USB_Check_Std_Request
USB_Get_Dsc_Handler
USB_Set_Cfg_Handler
USB_CB_Init_EP
USB_Get_Status_Handler
USB_Std_Feature_Req_Handler
USB_CB_Check_Other_Req
USB_Check_HID_Request
USB_CtrlEP_Service_Complete
USB_CtrlTrf_Tx_Service
USB_CtrlTrf_Out_Handler
USB_CtrlTrf_Rx_Service
USB_Prepare_Next_Setup_Trf
USB_CtrlTrf_In_Handler
USB_CtrlTrf_Tx_Service
USB_Prepare_Next_Setup_Trf


Example5_28BYJ48_PIC16F1459_mikroC.zip > USB.xml

USB.jpg



None
None
None
PreviewImage


Example5_28BYJ48_PIC16F1459_mikroC.zip > Example5_Stepper.c

unsigned char readbuff[64] absolute 0x040; // Buffers should be in USB RAM, please consult datasheet
unsigned char writebuff[64] absolute 0x140;

char cnt;
char kk;

void interrupt(){
USB_Interrupt_Proc(); // USB servicing is done inside the interrupt
}
typedef struct port_s {
int *bank;
int idx;
} port_t;

typedef struct motor_s {
port_t in[4];
int steps;
int direction;
int remLoops;
} motor_t;


void MOTOR_Init(motor_t *m, int *bank1, int bit1, int *bank2, int bit2, int *bank3, int bit3, int *bank4, int bit4);
void MOTOR_RunInternal(motor_t *m, int Steps);
void MOTOR_GoTo(motor_t *m, int dir, int loops);
void MOTOR_Stop(motor_t *m);
// call delay - Delay_us(2000);
void MOTOR_Run(motor_t *m);

void MOTOR_GoTo(motor_t *m, int dir, int loops)
{
m- & gt; direction = dir;
m- & gt; remLoops = loops;
}
void PORT_Init(port_t *p, int *bank, int biti)
{
p- & gt; bank = bank;
p- & gt; idx = biti;
}
void MOTOR_Init(motor_t *m, int *bank1, int bit1, int *bank2, int bit2, int *bank3, int bit3, int *bank4, int bit4)
{
m- & gt; steps = 0;
m- & gt; remLoops = 0;
m- & gt; direction = 1;
PORT_Init( & m- & gt; in[0],bank1,bit1);
PORT_Init( & m- & gt; in[1],bank2,bit2);
PORT_Init( & m- & gt; in[2],bank3,bit3);
PORT_Init( & m- & gt; in[3],bank4,bit4);
}
void PORT_SetTrue(port_t *p)
{
(*p- & gt; bank) |= 1 & lt; & lt; p- & gt; idx;
}
void PORT_SetFalse(port_t *p)
{
(*p- & gt; bank) & = ~(1 & lt; & lt; p- & gt; idx);
}
void PORT_Set(port_t *p, int i)
{
if(i)
{
PORT_SetTrue(p);
}
else
{
PORT_SetFalse(p);
}
}
#define LOW 0
#define HIGH 1
void MOTOR_Stop(motor_t *m)
{
m- & gt; steps = 0;
m- & gt; remLoops = 0;
m- & gt; direction = 1;
}
void MOTOR_Run(motor_t *m)
{
if(m- & gt; remLoops & lt; = 0)
{
PORT_Set( & m- & gt; in[0], LOW);
PORT_Set( & m- & gt; in[1], LOW);
PORT_Set( & m- & gt; in[2], LOW);
PORT_Set( & m- & gt; in[3], LOW);
return;
}
MOTOR_RunInternal(m,m- & gt; steps);
m- & gt; steps += m- & gt; direction;
if(m- & gt; steps & gt; 7)
{
m- & gt; steps = 0;
m- & gt; remLoops--;
}
if(m- & gt; steps & lt; 0)
{
m- & gt; steps = 7;
m- & gt; remLoops--;
}
}
// motor0 - RC0, RC1, RC2, RB4
void MOTOR_RunInternal(motor_t *m, int Steps)
{
switch(Steps){
case 0:
PORT_Set( & m- & gt; in[0], LOW);
PORT_Set( & m- & gt; in[1], LOW);
PORT_Set( & m- & gt; in[2], LOW);
PORT_Set( & m- & gt; in[3], HIGH);
break;
case 1:
PORT_Set( & m- & gt; in[0], LOW);
PORT_Set( & m- & gt; in[1], LOW);
PORT_Set( & m- & gt; in[2], HIGH);
PORT_Set( & m- & gt; in[3], HIGH);
break;
case 2:
PORT_Set( & m- & gt; in[0], LOW);
PORT_Set( & m- & gt; in[1], LOW);
PORT_Set( & m- & gt; in[2], HIGH);
PORT_Set( & m- & gt; in[3], LOW);
break;
case 3:
PORT_Set( & m- & gt; in[0], LOW);
PORT_Set( & m- & gt; in[1], HIGH);
PORT_Set( & m- & gt; in[2], HIGH);
PORT_Set( & m- & gt; in[3], LOW);
break;
case 4:
PORT_Set( & m- & gt; in[0], LOW);
PORT_Set( & m- & gt; in[1], HIGH);
PORT_Set( & m- & gt; in[2], LOW);
PORT_Set( & m- & gt; in[3], LOW);
break;
case 5:
PORT_Set( & m- & gt; in[0], HIGH);
PORT_Set( & m- & gt; in[1], HIGH);
PORT_Set( & m- & gt; in[2], LOW);
PORT_Set( & m- & gt; in[3], LOW);
break;
case 6:
PORT_Set( & m- & gt; in[0], HIGH);
PORT_Set( & m- & gt; in[1], LOW);
PORT_Set( & m- & gt; in[2], LOW);
PORT_Set( & m- & gt; in[3], LOW);
break;
case 7:
PORT_Set( & m- & gt; in[0], HIGH);
PORT_Set( & m- & gt; in[1], LOW);
PORT_Set( & m- & gt; in[2], LOW);
PORT_Set( & m- & gt; in[3], HIGH);
break;
default:
PORT_Set( & m- & gt; in[0], LOW);
PORT_Set( & m- & gt; in[1], LOW);
PORT_Set( & m- & gt; in[2], LOW);
PORT_Set( & m- & gt; in[3], LOW);
break;
}
}
void main(void){
int *ptr;
int i;
motor_t motorH;
motor_t motorV;


ADCON1 |= 0x0F; // Configure all ports with analog function as digital
OSCCON = 0b01111100; // 16MHz intosc


TRISB = 0;
PORTB = 0;
TRISA = 0;
PORTA = 0;
TRISC = 0;
PORTC = 0;

HID_Enable( & readbuff, & writebuff); // Enable HID communication

MOTOR_Init( & motorH, & LATC,0, & LATC, 1, & LATC,2, & LATB,4);
//MOTOR_Init( & motorV, & LATC,5, & LATC, 4, & LATC,3, & LATC,6);
MOTOR_Init( & motorV, & LATC,3, & LATC, 6, & LATC,7, & LATB,7);
if(0)
{
port_t test;
PORT_Init( & test, & LATC,0);
for(i = 0; i & lt; 210; i++)
{
// PORT_SetTrue( & test);
PORT_Set( & test,1);
Delay_ms(100);
// PORT_SetFalse( & test);
PORT_Set( & test,0);
Delay_ms(100);
}
}
if(0)
{
for(i = 0; i & lt; 210; i++)
{
PORT_Set( & motorH.in[0],1);
Delay_ms(100);
PORT_Set( & motorH.in[0],0);
Delay_ms(100);
}
}
if(0)
{
int *ptrLATA = & LATA;
int *ptrLATB = & LATB;
int *ptrLATC = & LATC;
for(i = 0; i & lt; 1210; i++)
{
Delay_ms(100);
(*ptrLATB) & = 0x0;
(*ptrLATA) & = 0x0;
(*ptrLATC) & = 0x0;
Delay_ms(100);
(*ptrLATB) |= 0xff;
(*ptrLATA) |= 0xff;
(*ptrLATC) |= 0xff;
}
}
if(0)
{
int *ptrLATA = & LATA;
int *ptrLATB = & LATB;
int *ptrLATC = & LATC;
for(i = 0; i & lt; 210; i++)
{
Delay_ms(100);
(*ptrLATB) = 0x0;
(*ptrLATA) = 0x0;
(*ptrLATC) = 0x0;
Delay_ms(100);
(*ptrLATB) = 0xff;
(*ptrLATA) = 0xff;
(*ptrLATC) = 0xff;
}
}
Delay_ms(1000);
LATB = 0x0;
LATA = 0x0;
LATC = 0x0;
Delay_ms(1000);
LATB = 0xff;
LATA = 0xff;
LATC = 0xff;
Delay_ms(1000);
LATB = 0x0;
LATA = 0x0;
LATC = 0x0;
Delay_ms(1000);
LATB = 0xff;
LATA = 0xff;
LATC = 0xff;


ptr = & LATA;

// PWM2CON = 0b11000000; //PWM2 module is enabled , Output to PWM2 pin is enabled (RC6, PIC16F1459)



motorH.remLoops = 5;
while(1)
{
motor_t *useMot = 0;
while(!HID_Read())
{
/* Delay_ms(100);
PORT_Set( & motorH.in[0], 0);
Delay_ms(100);
PORT_Set( & motorH.in[0], 1);

Delay_ms(100);
PORT_Set( & motorH.in[0], 0);

Delay_ms(100);
PORT_Set( & motorH.in[0], 1);

Delay_ms(100); */
/* Delay_ms(100);
LATB = 0x0;
LATA = 0x0;
LATC = 0x0;
Delay_ms(100);
LATB = 0xff;
LATA = 0xff;
LATC = 0xff; */

Delay_us(2000);
MOTOR_Run( & motorH);
MOTOR_Run( & motorV);
}

if(readbuff[0]==0)
{
useMot = & motorH;
}
else if(readbuff[0] == 1) {

useMot = & motorV;
}
else if(readbuff[0] == 2)
{
MOTOR_Stop( & motorH);
MOTOR_Stop( & motorV);
}
if(useMot!=0)
{
int wantDir ;
if(readbuff[1]==0)
{
wantDir = 1;
}
else{
wantDir = -1;
}
if(useMot- & gt; direction == wantDir)
{
useMot- & gt; remLoops += readbuff[2];
}
else{
useMot- & gt; remLoops = readbuff[2];
}
useMot- & gt; direction = wantDir;
}
// LATA = ~LATA;
// LATB = ~LATB;
// LATC = ~LATC;
}
}