2021年11月23日 星期二

Python set 集合運算


x = {"apple", "banana", "cherry"}
y = {"google", "sun", "apple"}
#交集
#z = x.intersection(y)
z=x&y
print(z)
#差集
#z2 = x.difference(y)
z2=x-y
print(z2)
#對稱差
#z3 = x.symmetric_difference(y)
z3=x^y
print(z3)
#聯集
#z4=x.union(y)
z4=x|y
print(z4)

2021年5月11日 星期二

Lg4j2 for JAVA動態網頁基礎使用(無maven)

每個Level有對應的intLevel整數值,數值越小等級越高,數值越大等級越低。

LevelintValue用途
OFF 0不輸出任何日誌
FETAL100造成應用程式停止的日誌
ERROR     
200造成應用程式錯誤的日誌
WARN300可能導致錯誤的日誌
INFO400一般資訊的日誌
DEBUG500除錯資訊的日誌
TRACE600更細的除錯資訊,通常用來追蹤程式流程的日誌
ALLInteger.MAX_VALUE輸出所有日誌

Logger輸出的等級大於等於Logger設定的等級時才會輸出訊息。

 高---------------------------------------低
 FETAL > ERROR > WARN > INFO > DEBUG > TRACE

要使用Log4j2需四個項目:(tomcat須為含7以上)

一.下載 apache Log4j2

     https://logging.apache.org/log4j/2.x/download.html

二.設定使用log4j-api-2.xxx.jar及log4j-core-2.xxx.ja進classpath

    如在Eclipse IDE中須將上述的兩個jar放入

     (a).webapps--> builderPath-->Libraries-->classpath

          可消除編輯程式碼的錯誤

     (b).DynamicWebProject下的WEB-INF/lib目錄

          可消除執行程式碼的錯誤

三.建立Log4j2的參數檔,檔名為log4j2開頭,副檔名及格式可為".properties","xml',"json" 

    以下是log4j2.xml範例

     ==================================================================

 <?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">  
   <Appenders>  
      <Console name="Console" target="SYSTEM_OUT">  
           <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />  
      </Console>  
   </Appenders>  
   <Loggers>  
       <Root level="info">  
           <AppenderRef ref="Console" />  
        </Root>  
    </Loggers>  
</Configuration>

     ==================================================================

   Log4j2的參數檔,放置位置有src,classpath及WEB-INF三個地方,JSP DynamicWebProject

   我建議 WEB-INF目錄

 四.Log4j2的servlet及jsp範例程式如下:

    ==================================================================

package com.lccnet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
/**
 * Servlet implementation class Servlet1
 */
@WebServlet("/Servlet1")
public class Servlet1 extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Servlet1() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        response.getWriter().append("Served at: ").append(request.getContextPath());
        Logger log = LogManager.getLogger(this.getClass());
        log.info("Show INFO message");
        log.warn("Show WARN message");
        log.error("Show ERROR message");
        log.fatal("Show FATAL message");
        /*
         * 高---------------------------------------低
         * FETAL > ERROR > WARN > INFO > DEBUG > TRACE
         * */

    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}
 

    ==================================================================

    ==================================================================

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="org.apache.logging.log4j.Logger,org.apache.logging.log4j.LogManager"%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
Hello World!
<%
Logger log = LogManager.getLogger(this.getClass());
log.info("Show INFO message");
log.warn("Show WARN message");
log.error("Show ERROR message");
log.fatal("Show FATAL message");
%>
</body>
</html>

    ==================================================================

2021年4月13日 星期二

Jsp init-param web.xml

 <servlet>

<servlet-name></srvlet-name>

<jsp-file></jsp>

<init-param>

<param-name></param-name>

<param-value></param-value>

</init-param>

</servlet> 

<%!

public void jspInit(){}

public void jspDestory(){}

%>

 ServletJSP
ApplicationgetServletContext().setAttribute(key,value);application.setAttribute(key,value);
Resquestrequest.setAttribute(key,value);request.setAttribute(key,value);
Sessionrequest.getSession().setAttribute(key,value);session.setAttribute(key,value);
PageNONEpageContext.setAttribute(key,value);

 

pageContextˋ這jsp隱含變數有一特殊功能可指定存取任何範圍的attribute

pageContext.setAttribute(key,value); -->page範圍

pageContext.setAttribute(key,value,PageContext.SESSION_SCOPE); -->session範圍

如不確定是哪一範圍可用

pageContext.findAttribute(key)尋找

isErrorPage

errorPage

<web-app>

<jsp-config>

    <jsp-property-group>

         <url-pattern>*.jsp</url-pattern>

         <scripting-invalid>true</scripting-invalid>

    </jsp-property-group>

</jsp-config> 

</web-app>

${application.sno} <!-- Expreesion Language use -->

2021年4月7日 星期三

6DofArm Raspberry pi SoftwarePWM測試程式python版

#-*- coding: UTF-8 -*- 

import RPi.GPIO as GPIO
import time

def angle_to_duty_cycle(angle=0):
    duty_cycle = (0.05 * SERVO_MOTOR_FREQUENCY) + (0.19 * SERVO_MOTOR_FREQUENCY * angle /  SERVO_MOTOR_ANGLE_MAX)
    return duty_cycle

def move_servo(pin, pwm, angle):
    dc = angle_to_duty_cycle(angle)
    pwm.ChangeDutyCycle(dc)
    print('第{: >2}軸 角度={: >3}, 工作週期={:.2f}'.format(pin, angle, dc))
    
def manual_control(pin, pwm):
    print('Move the servo manually (press "x" to exit).')
    input_data = None

    while True:
        input_data = input("Enter the angle: ")
        if input_data.lower() == 'x':
            break
        try:
            angle = int(input_data)
        except Exception:
            print('Either enter an integer or "x" to exit.')
            continue

        try:
            move_servo(pin, pwm, angle)
        except ValueError:
            print('The inputted angle is not valid.')
            continue

def automatic_control(pin, pwm):
    print('Move the servo with a test pattern.')
    angle=SERVO_MOTOR_ANGLE_MIN
    move_servo(pin, pwm, angle)
    time.sleep(3)
    angle=SERVO_MOTOR_ANGLE_MAX
    move_servo(pin, pwm, angle)
    time.sleep(3)
    angle=90
    move_servo(pin, pwm, angle)
    time.sleep(3)
    angle=110
    move_servo(pin, pwm, angle)
    time.sleep(3)

try:
    CONTROL_PIN1 = 4
    CONTROL_PIN2 = 17
    CONTROL_PIN3 = 22
    CONTROL_PIN4 = 23
    CONTROL_PIN5 = 24
    CONTROL_PIN6 = 27

    SERVO_MOTOR_ANGLE_MIN = 0  
    SERVO_MOTOR_ANGLE_MAX = 270 
    SERVO_MOTOR_FREQUENCY = 50

    GPIO.setmode(GPIO.BCM)
    GPIO.setup(CONTROL_PIN1, GPIO.OUT)
    GPIO.setup(CONTROL_PIN2, GPIO.OUT)
    GPIO.setup(CONTROL_PIN3, GPIO.OUT)
    GPIO.setup(CONTROL_PIN4, GPIO.OUT)
    GPIO.setup(CONTROL_PIN5, GPIO.OUT)
    GPIO.setup(CONTROL_PIN6, GPIO.OUT)

    pwmList=list()
    pwmList.append(GPIO.PWM(CONTROL_PIN1, SERVO_MOTOR_FREQUENCY))
    pwmList.append(GPIO.PWM(CONTROL_PIN2, SERVO_MOTOR_FREQUENCY))
    pwmList.append(GPIO.PWM(CONTROL_PIN3, SERVO_MOTOR_FREQUENCY))
    pwmList.append(GPIO.PWM(CONTROL_PIN4, SERVO_MOTOR_FREQUENCY))
    pwmList.append(GPIO.PWM(CONTROL_PIN5, SERVO_MOTOR_FREQUENCY))
    pwmList.append(GPIO.PWM(CONTROL_PIN6, SERVO_MOTOR_FREQUENCY))

    for pwm in pwmList:
        pwm.start(0)
        #pwm.ChangeDutyCycle(0)
    move_servo(1, pwmList[1], 50)
    #time.sleep(3)
    move_servo(2, pwmList[2], 45)
    #time.sleep(2)
    move_servo(3, pwmList[3], 90)
    #time.sleep(2)
    move_servo(0, pwmList[0], 75)
    #time.sleep(2)

    while True:
        input_data = input("What servo motor (channel) you want to control? ")
        try:
            servo_aix = int(input_data)
            if servo_aix < 0 or servo_aix > 5:
                raise ValueError

        except Exception:
            print('Enter an integer between 0 and 5.')
            continue

        input_data = str(input("What do you want to do?\n[1] Manual test\n[2] Automatic test\n[x] Exit\nAnswer: "))
        if input_data == '1':
            manual_control(servo_aix, pwmList[servo_aix])
        elif input_data == '2':
            automatic_control(servo_aix, pwmList[servo_aix])
        elif input_data.lower() == 'x':
            break
        else:
            print('Unrecognized input.')
            continue
except KeyboardInterrupt:
    print('關閉程式')

finally:
    for pwm in pwmList:
        pwm.stop(0)
    GPIO.cleanup()

2021年3月31日 星期三

Raspberry Pi硬體PWM控制舵機Servo Moto

BCM 編號 12, 13, 18, 19 的四隻腳位,有支援硬體 PWM 功能 

duty_cycle工作週期計算公式來由:

Python 套件所指定 PWM 是工作週期而非脈衝寬度,所以我們必須先進行轉換。

當頻率為 50 Hz 時,則每一個週期為 1/50 = 0.02 秒,也就是 20 毫秒 (ms)。

1 ms 的脈衝寬度其工作週期為 1 / 20 * 100% = 5%。

故PWM 的頻率設定為 50 Hz,然後控制工作週期在 5~10% 之間,就可以從 -90 度旋轉到 +90 度(0~180度)。

旋轉角度工作週期 (當頻率為 50 Hz 時) 
0 度5%
45 度6.25%
90 度7.5%
135 度8.75%
180 度10%

 

另外舵機當頻率一般5V供電50HZ時0.5ms為0度佔2.5%,2.4ms為180度佔12%

 


  

要使用Raspberry pi的硬體PWM需啟動pigpio daeman

指令如左:systemctl start pigpiod

python 測試程式如下:

import pigpio
import time
 
PWM_CONTROL_PIN = 18#(18是BCM腳位,實體腳位是12)
PWM_FREQ = 50#頻率50HZ
STEP = 15
 
pi = pigpio.pi()
 
def angle_to_duty_cycle(angle=0):
    duty_cycle = int((500 * PWM_FREQ + (1900 * PWM_FREQ * angle / 180)))
    return duty_cycle

    #一般舵機是500~2400ms,轉0~180度

    #MG996R舵機似乎是771~2193ms
 
try:
    print('按下 Ctrl-C 可停止程式')
    for angle in range(0, 181, STEP):
        dc = angle_to_duty_cycle(angle)
        print('角度={: >3}, 工作週期={: >6}'.format(angle, dc))
        pi.hardware_PWM(PWM_CONTROL_PIN, PWM_FREQ, dc)
        time.sleep(0.5)
    for angle in range(180, -1, -STEP):
        dc = angle_to_duty_cycle(angle)
        print('角度={: >3}, 工作週期={: >6}'.format(angle, dc))
        pi.hardware_PWM(PWM_CONTROL_PIN, PWM_FREQ, dc)
        time.sleep(0.5)
    pi.hardware_PWM(PWM_CONTROL_PIN, PWM_FREQ, angle_to_duty_cycle(90))
    while True:
        next
except KeyboardInterrupt:
    print('關閉程式')
finally:
    pi.set_mode(PWM_CONTROL_PIN, pigpio.INPUT)#恢復腳位預設狀態