Friday, May 27, 2016

Avoiding Linker Error: Multiple Definition

Avoiding Linker Error: Multiple Definition

The Types of Compilation Errors
First, let's distinguish between the types of errors: most compilers will give three types of compile-time alerts: compiler warnings, compiler errors, and linker errors.

 As in the below program define the variables as extern in Controller.h file and normal declaration Controller.c file, Program should compile and no Link error.

In the header files use the  pre-process directives as below,

#ifndef CONTROLLER_LAYER_H
#define CONTROLLER_LAYER_H

your code here.,......

#endif
the above would allow you to include this header file in n number of other files. You might get a linker error when defining variables, see the below example for solution


Controller.h
#ifndef CONTROLLER_LAYER_H
#define CONTROLLER_LAYER_H

#include "stdint.h"

extern char *pui8IncomingBuffer;
extern char *pui8OutgoingBuffer;

void controllerFunc(void);


#endif

Controller.c
#include "Controller.h"
#include "ProtocolLayer.h"
char *pui8IncomingBuffer;
char *pui8OutgoingBuffer;

void controllerFunc(void)
{
pui8IncomingBuffer = "{50, 0101,01,02,03,56,}";
  
}

Python Program for Motion Detection and Video Recording using Raspberry Pi

Program detect the Motion in the camera, records the video for 5 Seconds and e-mails the Recorded video file.

Steps:
Create/Open a file name CameraMotionDetection.py, copy paste the below code.

Points to be Noted:
1) Provide your email Id for the below variable
  strFrom = "Sender Email Id"
  strTo = " Receivers Email Id"
 2) Make sure if your using Gmail account enable lesser secure apps options, below link is for gmail account.
    https://www.google.com/settings/security/lesssecureapps
  if not enable your program would terminate with an error Authorization failed.
3) Make sure you provide the correct sender password and valid email ID.


#The MIT License (MIT)
#Copyright (c) 2014 Ron Ostafichuk
#
#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
#in the Software without restriction, including without limitation the rights
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#copies of the Software, and to permit persons to whom the Software is
#furnished to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in all
#copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
#SOFTWARE.
# Command to execute the Video omxplayer video.h264
import io
import os
import time
import picamera
import numpy as np
from time import sleep

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
from email.mime.image import MIMEImage
import smtplib

widthH = 2592 # too slow for motion check, only use for the save sequence 
heightH = 1944
width = 1440 # use lower resolution for motion check
height = 1080

threshold = 30 # how much must the color value (0-255) change to be considered a change
minPixelsChanged = width * height * 2 / 100 # % change  # how many pixels must change to begin a save sequence
print("minPixelsChanged=",minPixelsChanged) # debug

print ('Creating in-memory stream')
stream = io.BytesIO()
step = 1  # use this to toggle where the image gets saved
numImages = 1 # count number of images processed
captureCount = 0 # flag used to begin a sequence capture

strFrom = 'SenderEmailId@gmail.com'
strTo = 'ReceiverEmailID@yahoo.com' 

# function to generate a sequence of 20 filenames for the picamera capture_sequence command to use
def filenames():
    frame = 0
    fileName = time.strftime("NAS/%Y%m%d/%Y%m%d-%H%M%S-",time.localtime())
    while frame < 20:
        yield '%s%02d.jpg' % (fileName, frame)
        frame += 1

def send_mail(send_from, send_to, subject, text, file):    
    msg = MIMEMultipart()
    msg['From'] = strFrom
    msg['To'] = send_to
    msg['Date'] = " Use any date time module to insert or use email.utils formatdate"
    msg['Subject'] = subject
    
    msg.attach( MIMEText(text) )
    part = MIMEBase('application', "octet-stream")
    fo=open('/home/pi/video.h264',"rb")
    part.set_payload(fo.read() )
    encoders.encode_base64(part)
    part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(file))
    msg.attach(part)

    smtp = smtplib.SMTP('smtp.gmail.com',587) #Email id  for yahoo use smtp.mail.yahoo.com
    #smtp.ehlo()    
    smtp.starttls()  #in gmail use smtplib.SMTP_SSL()
    #smtp.ehlo()
    smtp.login(strFrom,'SendersPassword') #Edit
    sent=smtp.sendmail(send_from, send_to, msg.as_string())
    smtp.close()
    return sent    

# begin monitoring
with picamera.PiCamera() as camera:
    time.sleep(1) # let camera warm up
    try:
        while threshold > 0:
            camera.resolution = (1440,1080) # use a smaller resolution for higher speed compare

            print ('Capture ' , numImages)
            if step == 1:
                stream.seek(0)
                camera.capture(stream, 'rgba',True) # use video port for high speed
                data1 = np.fromstring(stream.getvalue(), dtype=np.uint8)
                step = 2
            else:
                stream.seek(0)
                camera.capture(stream, 'rgba',True)
                data2 = np.fromstring(stream.getvalue(), dtype=np.uint8)
                step = 1
            numImages = numImages + 1

            if numImages > 4:  # ignore first few images because if the camera is not quite ready it will register as motion right away
                # look for motion unless we are in save mode
                if captureCount <= 0:
                    print("Compare")
                    # not capturing, test for motion (very simplistic, but works good enough for my purposes)
                    data3 = np.abs(data1 - data2)  # get difference between 2 successive images
                    numTriggers = np.count_nonzero(data3 > threshold) / 4 / threshold #there are 4 times the number of pixels due to rgba

                    #print("Trigger cnt=",numTriggers)

                    if numTriggers > minPixelsChanged:
                        captureCount = 1 # capture ? sequences in a row
                        # make sure directory exists for today
                        d = time.strftime("NAS/%Y%m%d") #unfortunately this saves as UTC time instead of local, will fix it later sorry
                        if not os.path.exists(d):
                            os.makedirs(d)

                if captureCount > 0:
                   # in capture mode, save an image in hi res
                   # camera.resolution = (widthH,heightH)
                    print("Capturing Video Please wait..") 
                    sleep(1)
                    camera.start_preview()
                    camera.start_recording('/home/pi/video.h264')
                    sleep(5)
                    camera.stop_recording()
                    camera.stop_preview()
                    print("Saving Video Please wait..")
                    sleep(5)
                    print("Mailing Video Please wait..%s" % strTo)
                    print("It will take Several Minutes...")
                    s=send_mail(strFrom,strTo,"Security Breach !!","Video Attached","/home/pi/video.h264")
                   # dtFileStr = time.strftime("NAS/%Y%m%d/%Y%m%d-%H%M%S-00.jpg",time.localtime()) # once again, UTC time instead of local time
                   # print("Saving sequence ",dtFileStr)
                    # save full resolution images to the NAS
                   # camera.capture_sequence(filenames(),'jpeg',use_video_port=True, quality=92)
                    captureCount = captureCount-1
                    print("Video Sent..Sucessfully")

    finally:
        camera.close()
        print ('Program Terminated')