PB -8- Arduino email gönderme

Arduino, kapı açılınca, seri porttan bilgisayara “1” karakteri yollar. Ardından PureBasic, istenen adrese mail atar. Bunun için önce ücretsiz olan bir yaani mail adresi aldım.

image

Test için bir buton da kullanabilirsin. Ama bu işi yapacaksan manyetik kapı alarm sensörü alman gerekecektir. Aşağıdaki kodu Arduino’ya yüklüyoruz..

#define SENSOR 2   
 bool durum = 0;
 void setup() {
   pinMode(SENSOR, INPUT_PULLUP);             
   Serial.begin(9600);           
   attachInterrupt(0, kapi_acildi, RISING); 
 }
 void loop() {
   delay(1000);
 }
 void kapi_acildi()
 {
   durum = digitalRead(SENSOR); 
   Serial.println(durum);      
   delay(1000);
 }



Yine Mk-soft’un thread kodunu kullanıyoruz. InitComport() prosedüründe bulunan Baud ve Port ayarlarını kendine göre ayarlaman gerekiyor.

;-TOP
; https://www.purebasic.fr/english/viewtopic.php?t=79759
; Comment : Comport Manager Over Thread and Callback
; Author  : mk-soft
; Version : v0.07.1
; Created : 26.01.2018
; Updated : 03.09.2022
; *****************************************************************************
CompilerIf #PB_Compiler_Thread = 0
  CompilerError "Use Option Threadsafe!"
CompilerEndIf

Prototype ProtoReceiveCB(Text.s)
Prototype ProtoStatusCB(Status, *ComData)

Enumeration
  #ComThread_Stopped
  #ComThread_Startup
  #ComThread_Running
EndEnumeration

Enumeration
  #ComStatus_Nothing
  #ComStatus_OpenPort
  #ComStatus_ClosePort
  #ComStatus_ErrorOpenPort
  #ComStatus_ErrorSend
  #ComStatus_ErrorReceive
  #ComStatus_ErrorDataSize
EndEnumeration

Structure udtComData
  ; Header
  ThreadID.i
  Exit.i
  Status.i
  ; Port Data
  ComID.i
  Port.s
  Baud.i
  Parity.i
  DataBit.i
  StopBit.i
  Handshake.i
  BufferSize.i
  ; End Of Text
  EndOfText.s
  ; Send Data
  SendSignal.i
  SendCount.i
  SendText.s
  SendError.i
  ; Receive data
  ReceiveCount.i
  ReceiveText.s
  ReceiveError.i
  ; Callback
  *StatusCB.ProtoStatusCB
  *ReceiveCB.ProtoReceiveCB
EndStructure

Procedure thComport(*ComData.udtComData)
  
  Protected *Send, *Receive, SendText.s, SendLen, ReceiveText.s, ReceiveLen, Pos
  
  With *ComData
    ; Startup
    \Status = #ComThread_Startup
    \SendCount = 0
    \ReceiveCount = 0
    \ComID = OpenSerialPort(#PB_Any, \Port, \Baud, \Parity, \DataBit, \StopBit, \Handshake, \BufferSize, \BufferSize)
    If \ComID
      \Status = #ComThread_Running
    Else
      If \StatusCB
        \StatusCB(#ComStatus_ErrorOpenPort, *ComData)
      EndIf
      \Status = #ComThread_Stopped
      ProcedureReturn 0
    EndIf
    If \StatusCB
      \StatusCB(#ComStatus_OpenPort, *ComData)
    EndIf
    *Send = AllocateMemory(\BufferSize)
    *Receive = AllocateMemory(\BufferSize)
    ; Loop
    Repeat
      If \SendSignal
        SendText = \SendText + \EndOfText
        SendLen = StringByteLength(SendText, #PB_Ascii)
        If SendLen <= \BufferSize
          PokeS(*Send, SendText, SendLen, #PB_Ascii)
          If WriteSerialPortData(\ComID, *Send, SendLen) = 0
            \SendError = SerialPortError(\ComID)
            If \StatusCB
              \StatusCB(#ComStatus_ErrorSend, *ComData)
            EndIf
          Else
            \SendError = 0
            \SendCount + 1
          EndIf
        Else
          If \StatusCB
            \StatusCB(#ComStatus_ErrorDataSize, *ComData)
          EndIf
        EndIf
        \SendSignal = #False
      EndIf
      ReceiveLen = AvailableSerialPortInput(\ComID)
      If ReceiveLen
        ReceiveLen = ReadSerialPortData(\ComID, *Receive, ReceiveLen)
        If ReceiveLen = 0
          \ReceiveError = SerialPortError(\ComID)
          If \StatusCB
            \StatusCB(#ComStatus_ErrorReceive, *ComData)
          EndIf
        Else
          \ReceiveError = 0
        EndIf
        ReceiveText + PeekS(*Receive, ReceiveLen, #PB_Ascii)
        Repeat
          pos = FindString(ReceiveText, \EndOfText, 1, #PB_String_NoCase)
          If pos
            \ReceiveText = Left(ReceiveText, pos - 1)
            ReceiveText = Mid(ReceiveText, pos + Len(\EndOfText))
            \ReceiveCount + 1
            If \ReceiveCB
              \ReceiveCB(\ReceiveText)
            EndIf
          EndIf
        Until pos = 0
      EndIf
      Delay(10)
    Until \Exit
    ; Shutdown
    CloseSerialPort(\ComID)
    If \StatusCB
      \StatusCB(#ComStatus_ClosePort, *ComData)
    EndIf
    FreeMemory(*Send)
    FreeMemory(*Receive)
    \Status = #ComThread_Stopped
    \ComID = 0
    \Exit = 0
    ProcedureReturn 1
  EndWith
  
EndProcedure
; ----
Procedure.s SerialPortErrorText(ErrorCode)
  Protected r1.s
  
  Select ErrorCode
    Case #PB_SerialPort_RxOver      : r1 = "An input buffer overflow has occurred."
    Case #PB_SerialPort_OverRun     : r1 = "A character-buffer overrun has occurred."
    Case #PB_SerialPort_RxParity    : r1 = "The hardware detected a parity error."
    Case #PB_SerialPort_Frame       : r1 = "The hardware detected a framing error."
    Case #PB_SerialPort_Break       : r1 = "The hardware detected a break condition."
    Case #PB_SerialPort_TxFull      : r1 = "The application tried to transmit a character but the output buffer was full."
    Case #PB_SerialPort_IOE         : r1 = "An I/O error occurred during communications with the device."
    Case #PB_SerialPort_WaitingCTS  : r1 = "Specifies whether transmission is waiting for the CTS (clear-To-send) signal to be sent."
    Case #PB_SerialPort_WaitingDSR  : r1 = "Specifies whether transmission is waiting for the DSR (Data-set-ready) signal to be sent."
    Case #PB_SerialPort_WaitingRLSD : r1 = "Specifies whether transmission is waiting for the RLSD (receive-line-signal-detect) signal to be sent."
    Case #PB_SerialPort_XoffReceived: r1 = "Specifies whether transmission is waiting because the XOFF character was received."
    Case #PB_SerialPort_XoffSent    : r1 = "Specifies whether transmission is waiting because the XOFF character was transmitted."
    Case #PB_SerialPort_EOFSent     : r1 = "Specifies whether the end-of-file (EOF) character has been received."
    Default                         : r1 = "ErrorCode " + Hex(ErrorCode)
  EndSelect
  ProcedureReturn r1
EndProcedure
; ----
; Threaded String Helper

Procedure AllocateString(String.s)
  Protected *mem
  *mem = AllocateMemory(StringByteLength(String) + SizeOf(Character))
  If *mem
    PokeS(*mem, String)
  EndIf
  ProcedureReturn *mem
EndProcedure

Procedure.s FreeString(*Mem)
  Protected result.s
  If *Mem
    result = PeekS(*Mem)
    FreeMemory(*Mem)
  EndIf
  ProcedureReturn result
EndProcedure

; *****************************************************************************
;- Example

CompilerIf #PB_Compiler_IsMainFile
  
  Global ComData.udtComData, TimePass
  
  Enumeration EventCustomValue #PB_Event_FirstCustomValue
    #My_Event_NewData
    #My_Event_NewState
  EndEnumeration
  ; ---------------------------------------------------------------------------
  Procedure ReceiveCB(Text.s)
    PostEvent(#My_Event_NewData, 0, 0, 0, AllocateString(Text))
  EndProcedure
  
  Procedure MyEventNewDataCB()
    Protected Text.s, TimeDiff
    TimeDiff = ElapsedMilliseconds() - TimePass
    TimePass = ElapsedMilliseconds()
    Text = FreeString(EventData())
    If TimeDiff > 200 And Text = "1"

      CreateMail(0, "erol.iscioglu@yaani.com", "Kapı açıldı!") ; Gönderen
      SetMailBody(0, "Merhaba!" + #CRLF$ +
                     "Kapı açıldı" + #CRLF$ +
                     "haberin olsun.")

      AddMailRecipient(0, "erol.iscioglu@yaani.com", #PB_Mail_To) ; Kime
      ; Set the SMTP server to use
      Result = SendMail(0, "smtp.yaanimail.com", 587, #PB_Mail_Asynchronous | #PB_Mail_UseSSL, 
                        "erol.iscioglu@yaani.com", "*******") ; kendi email ve parolanı gir
      
      Repeat
        Progress = MailProgress(0)
        Delay(300) 
      Until Progress = #PB_Mail_Finished Or Progress = #PB_Mail_Error
      Text = FormatDate("%dd.%mm.%yyyy", Date()) + Space(2) + FormatDate("%hh:%ii:%ss", Date()) + Space(6) 
      If Progress = #PB_Mail_Finished
        AddGadgetItem(0, -1, Text + "Mail sent!")
        SetGadgetState(0, CountGadgetItems(0) - 1)
        SetGadgetState(0, -1)
      Else
        AddGadgetItem(0, -1, Text + "Can't send the mail!")
        SetGadgetState(0, CountGadgetItems(0) - 1)
        SetGadgetState(0, -1)
      EndIf
    EndIf 
  EndProcedure
  
  BindEvent(#My_Event_NewData, @MyEventNewDataCB())
  ; ---------------------------------------------------------------------------
  Procedure StatusCB(Status, *ComData.udtComData)
    PostEvent(#My_Event_NewState, 0, 0, Status, *ComData)
  EndProcedure
  
  Procedure MyEventNewStateCB()
    Protected Text.s, Status, *ComData.udtComData
    Status = EventType()
    *ComData = EventData()
    Select Status
      Case #ComStatus_OpenPort
        Text = "ComStatus: Open Port " + *ComData\Port
      Case #ComStatus_ClosePort
        Text = "ComStatus: Close Port " + *ComData\Port
      Case #ComStatus_ErrorOpenPort
        Text = "ComError: Open Port " + *ComData\Port
      Case #ComStatus_ErrorSend
        Text = "ComError Send: Port " + *ComData\Port + " - " + SerialPortErrorText(*ComData\SendError)
      Case #ComStatus_ErrorReceive
        Text = "ComError Receive: Port " + *ComData\Port + " - " + SerialPortErrorText(*ComData\ReceiveError)
      Case #ComStatus_ErrorDataSize
        Text = "ComError Send: Port " + *ComData\Port + " - Send data size to big."
    EndSelect
    If Bool(Text)
      StatusBarText(0, 0, Text)
    EndIf
  EndProcedure
  
  BindEvent(#My_Event_NewState, @MyEventNewStateCB())
  
  ; ---------------------------------------------------------------------------
  
  Procedure InitComport()
    With ComData
      If \Status
        ProcedureReturn 2 ; Always running
      EndIf
      \Port = "COM3"
      \Baud = 9600
      \Parity = #PB_SerialPort_NoParity
      \DataBit = 8
      \StopBit = 1
      \Handshake = #PB_SerialPort_NoHandshake
      \BufferSize = 2048
      \EndOfText = #CRLF$
      \StatusCB = @StatusCB()
      \ReceiveCB = @ReceiveCB()
      \ThreadID = CreateThread(@thComport(), ComData)
      If Not \ThreadID
        ProcedureReturn 0 ; Error create thread
      Else
        ProcedureReturn 1 ; ok
      EndIf
    EndWith
  EndProcedure
  
  Procedure Main()
    
    Protected Event, Text.s, i
    If OpenWindow(0, #PB_Ignore, #PB_Ignore, 320, 330, "Send mail", #PB_Window_SystemMenu)
      CreateStatusBar(0, WindowID(0))
      AddStatusBarField(#PB_Ignore)
      ListViewGadget(0, 10, 10, 300, 260)
      ButtonGadget(3, 220, 276, 90, 25, "On/Off")
      
      Repeat
        Event = WaitWindowEvent()
        Select Event
          Case #PB_Event_CloseWindow
            If ComData\Status
              MessageRequester("Info", "Comport Is Open!", #PB_MessageRequester_Warning)
            Else
              Break
            EndIf
            
          Case #PB_Event_Gadget
            Select EventGadget()

              Case 3 ; on/off button
                If ComData\Status
                  ComData\Exit = 1
                Else
                  If Not InitComport()
                    StatusBarText(0, 0, "Comport " + ComData\Port + ": Error Create Thread")
                  EndIf
                EndIf
            EndSelect
        EndSelect
      ForEver
    EndIf
  EndProcedure : Main()
  
CompilerEndIf



image



Written on October 3, 2024